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 "srv_spoolss_util.h"
25 #include "../librpc/gen_ndr/ndr_spoolss.h"
26 #include "../librpc/gen_ndr/ndr_winreg_c.h"
27 #include "../librpc/gen_ndr/ndr_security.h"
29 #include "rpc_server/rpc_ncacn_np.h"
30 #include "../libcli/security/security.h"
31 #include "rpc_client/cli_winreg.h"
32 #include "../libcli/registry/util_reg.h"
33 #include "../lib/tsocket/tsocket.h"
34 #include "printing/nt_printing_os2.h"
35 #include "rpc_client/init_spoolss.h"
37 #define TOP_LEVEL_PRINT_KEY "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print"
38 #define TOP_LEVEL_PRINT_PRINTERS_KEY TOP_LEVEL_PRINT_KEY "\\Printers"
39 #define TOP_LEVEL_CONTROL_KEY "SYSTEM\\CurrentControlSet\\Control\\Print"
40 #define TOP_LEVEL_CONTROL_FORMS_KEY TOP_LEVEL_CONTROL_KEY "\\Forms"
42 #define EMPTY_STRING ""
44 #define FILL_STRING(mem_ctx, in, out) \
46 if (in && strlen(in)) { \
47 out = talloc_strdup(mem_ctx, in); \
49 out = talloc_strdup(mem_ctx, ""); \
51 W_ERROR_HAVE_NO_MEMORY(out); \
54 #define CHECK_ERROR(result) \
55 if (W_ERROR_IS_OK(result)) continue; \
56 if (W_ERROR_EQUAL(result, WERR_NOT_FOUND)) result = WERR_OK; \
57 if (!W_ERROR_IS_OK(result)) break
59 /* FLAGS, NAME, with, height, left, top, right, bottom */
60 static const struct spoolss_FormInfo1 builtin_forms1[] = {
61 { SPOOLSS_FORM_BUILTIN, "10x11", {0x3e030,0x44368}, {0x0,0x0,0x3e030,0x44368} },
62 { SPOOLSS_FORM_BUILTIN, "10x14", {0x3e030,0x56d10}, {0x0,0x0,0x3e030,0x56d10} },
63 { SPOOLSS_FORM_BUILTIN, "11x17", {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} },
64 { SPOOLSS_FORM_BUILTIN, "12x11", {0x4a724,0x443e1}, {0x0,0x0,0x4a724,0x443e1} },
65 { SPOOLSS_FORM_BUILTIN, "15x11", {0x5d048,0x44368}, {0x0,0x0,0x5d048,0x44368} },
66 { SPOOLSS_FORM_BUILTIN, "6 3/4 Envelope", {0x167ab,0x284ec}, {0x0,0x0,0x167ab,0x284ec} },
67 { SPOOLSS_FORM_BUILTIN, "9x11", {0x37cf8,0x44368}, {0x0,0x0,0x37cf8,0x44368} },
68 { SPOOLSS_FORM_BUILTIN, "A0", {0xcd528,0x122488},{0x0,0x0,0xcd528,0x122488} },
69 { SPOOLSS_FORM_BUILTIN, "A1", {0x91050,0xcd528}, {0x0,0x0,0x91050,0xcd528} },
70 { SPOOLSS_FORM_BUILTIN, "A2", {0x668a0,0x91050}, {0x0,0x0,0x668a0,0x91050} },
71 { SPOOLSS_FORM_BUILTIN, "A3 Extra Transverse", {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} },
72 { SPOOLSS_FORM_BUILTIN, "A3 Extra", {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} },
73 { SPOOLSS_FORM_BUILTIN, "A3 Rotated", {0x668a0,0x48828}, {0x0,0x0,0x668a0,0x48828} },
74 { SPOOLSS_FORM_BUILTIN, "A3 Transverse", {0x48828,0x668a0}, {0x0,0x0,0x48828,0x668a0} },
75 { SPOOLSS_FORM_BUILTIN, "A3", {0x48828,0x668a0}, {0x0,0x0,0x48828,0x668a0} },
76 { SPOOLSS_FORM_BUILTIN, "A4 Extra", {0x397c2,0x4eb16}, {0x0,0x0,0x397c2,0x4eb16} },
77 { SPOOLSS_FORM_BUILTIN, "A4 Plus", {0x33450,0x50910}, {0x0,0x0,0x33450,0x50910} },
78 { SPOOLSS_FORM_BUILTIN, "A4 Rotated", {0x48828,0x33450}, {0x0,0x0,0x48828,0x33450} },
79 { SPOOLSS_FORM_BUILTIN, "A4 Small", {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
80 { SPOOLSS_FORM_BUILTIN, "A4 Transverse", {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
81 { SPOOLSS_FORM_BUILTIN, "A4", {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
82 { SPOOLSS_FORM_BUILTIN, "A5 Extra", {0x2a7b0,0x395f8}, {0x0,0x0,0x2a7b0,0x395f8} },
83 { SPOOLSS_FORM_BUILTIN, "A5 Rotated", {0x33450,0x24220}, {0x0,0x0,0x33450,0x24220} },
84 { SPOOLSS_FORM_BUILTIN, "A5 Transverse", {0x24220,0x33450}, {0x0,0x0,0x24220,0x33450} },
85 { SPOOLSS_FORM_BUILTIN, "A5", {0x24220,0x33450}, {0x0,0x0,0x24220,0x33450} },
86 { SPOOLSS_FORM_BUILTIN, "A6 Rotated", {0x24220,0x19a28}, {0x0,0x0,0x24220,0x19a28} },
87 { SPOOLSS_FORM_BUILTIN, "A6", {0x19a28,0x24220}, {0x0,0x0,0x19a28,0x24220} },
88 { SPOOLSS_FORM_BUILTIN, "B4 (ISO)", {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} },
89 { SPOOLSS_FORM_BUILTIN, "B4 (JIS) Rotated", {0x58de0,0x3ebe8}, {0x0,0x0,0x58de0,0x3ebe8} },
90 { SPOOLSS_FORM_BUILTIN, "B4 (JIS)", {0x3ebe8,0x58de0}, {0x0,0x0,0x3ebe8,0x58de0} },
91 { SPOOLSS_FORM_BUILTIN, "B5 (ISO) Extra", {0x31128,0x43620}, {0x0,0x0,0x31128,0x43620} },
92 { SPOOLSS_FORM_BUILTIN, "B5 (JIS) Rotated", {0x3ebe8,0x2c6f0}, {0x0,0x0,0x3ebe8,0x2c6f0} },
93 { SPOOLSS_FORM_BUILTIN, "B5 (JIS) Transverse", {0x2c6f0,0x3ebe8}, {0x0,0x0,0x2c6f0,0x3ebe8} },
94 { SPOOLSS_FORM_BUILTIN, "B5 (JIS)", {0x2c6f0,0x3ebe8}, {0x0,0x0,0x2c6f0,0x3ebe8} },
95 { SPOOLSS_FORM_BUILTIN, "B6 (JIS) Rotated", {0x2c6f0,0x1f400}, {0x0,0x0,0x2c6f0,0x1f400} },
96 { SPOOLSS_FORM_BUILTIN, "B6 (JIS)", {0x1f400,0x2c6f0}, {0x0,0x0,0x1f400,0x2c6f0} },
97 { SPOOLSS_FORM_BUILTIN, "C size sheet", {0x696b8,0x886d0}, {0x0,0x0,0x696b8,0x886d0} },
98 { SPOOLSS_FORM_BUILTIN, "D size sheet", {0x886d0,0xd2d70}, {0x0,0x0,0x886d0,0xd2d70} },
99 { SPOOLSS_FORM_BUILTIN, "Double Japan Postcard Rotated", {0x24220,0x30d40}, {0x0,0x0,0x24220,0x30d40} },
100 { SPOOLSS_FORM_BUILTIN, "E size sheet", {0xd2d70,0x110da0},{0x0,0x0,0xd2d70,0x110da0} },
101 { SPOOLSS_FORM_BUILTIN, "Envelope #10", {0x19947,0x3ae94}, {0x0,0x0,0x19947,0x3ae94} },
102 { SPOOLSS_FORM_BUILTIN, "Envelope #11", {0x1be7c,0x40565}, {0x0,0x0,0x1be7c,0x40565} },
103 { SPOOLSS_FORM_BUILTIN, "Envelope #12", {0x1d74a,0x44368}, {0x0,0x0,0x1d74a,0x44368} },
104 { SPOOLSS_FORM_BUILTIN, "Envelope #14", {0x1f018,0x47504}, {0x0,0x0,0x1f018,0x47504} },
105 { SPOOLSS_FORM_BUILTIN, "Envelope #9", {0x18079,0x37091}, {0x0,0x0,0x18079,0x37091} },
106 { SPOOLSS_FORM_BUILTIN, "Envelope B4", {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} },
107 { SPOOLSS_FORM_BUILTIN, "Envelope B5", {0x2af80,0x3d090}, {0x0,0x0,0x2af80,0x3d090} },
108 { SPOOLSS_FORM_BUILTIN, "Envelope B6", {0x2af80,0x1e848}, {0x0,0x0,0x2af80,0x1e848} },
109 { SPOOLSS_FORM_BUILTIN, "Envelope C3", {0x4f1a0,0x6fd10}, {0x0,0x0,0x4f1a0,0x6fd10} },
110 { SPOOLSS_FORM_BUILTIN, "Envelope C4", {0x37e88,0x4f1a0}, {0x0,0x0,0x37e88,0x4f1a0} },
111 { SPOOLSS_FORM_BUILTIN, "Envelope C5", {0x278d0,0x37e88}, {0x0,0x0,0x278d0,0x37e88} },
112 { SPOOLSS_FORM_BUILTIN, "Envelope C6", {0x1bd50,0x278d0}, {0x0,0x0,0x1bd50,0x278d0} },
113 { SPOOLSS_FORM_BUILTIN, "Envelope C65", {0x1bd50,0x37e88}, {0x0,0x0,0x1bd50,0x37e88} },
114 { SPOOLSS_FORM_BUILTIN, "Envelope DL", {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} },
115 { SPOOLSS_FORM_BUILTIN, "Envelope Invite", {0x35b60,0x35b60}, {0x0,0x0,0x35b60,0x35b60} },
116 { SPOOLSS_FORM_BUILTIN, "Envelope Monarch", {0x18079,0x2e824}, {0x0,0x0,0x18079,0x2e824} },
117 { SPOOLSS_FORM_BUILTIN, "Envelope", {0x1adb0,0x38270}, {0x0,0x0,0x1adb0,0x38270} },
118 { SPOOLSS_FORM_BUILTIN, "Executive", {0x2cf56,0x411cc}, {0x0,0x0,0x2cf56,0x411cc} },
119 { SPOOLSS_FORM_BUILTIN, "Folio", {0x34b5c,0x509d8}, {0x0,0x0,0x34b5c,0x509d8} },
120 { SPOOLSS_FORM_BUILTIN, "German Legal Fanfold", {0x34b5c,0x509d8}, {0x0,0x0,0x34b5c,0x509d8} },
121 { SPOOLSS_FORM_BUILTIN, "German Std Fanfold", {0x34b5c,0x4a6a0}, {0x0,0x0,0x34b5c,0x4a6a0} },
122 { SPOOLSS_FORM_BUILTIN, "Japan Envelope Chou #3 Rotated", {0x395f8,0x1d4c0}, {0x0,0x0,0x395f8,0x1d4c0} },
123 { SPOOLSS_FORM_BUILTIN, "Japan Envelope Chou #4 Rotated", {0x320c8,0x15f90}, {0x0,0x0,0x320c8,0x15f90} },
124 { SPOOLSS_FORM_BUILTIN, "Japan Envelope Kaku #2 Rotated", {0x510e0,0x3a980}, {0x0,0x0,0x510e0,0x3a980} },
125 { SPOOLSS_FORM_BUILTIN, "Japan Envelope Kaku #3 Rotated", {0x43a08,0x34bc0}, {0x0,0x0,0x43a08,0x34bc0} },
126 { SPOOLSS_FORM_BUILTIN, "Japan Envelope You #4 Rotated", {0x395f8,0x19a28}, {0x0,0x0,0x395f8,0x19a28} },
127 { SPOOLSS_FORM_BUILTIN, "Japan Envelope You #4", {0x19a28,0x395f8}, {0x0,0x0,0x19a28,0x395f8} },
128 { SPOOLSS_FORM_BUILTIN, "Japanese Double Postcard", {0x30d40,0x24220}, {0x0,0x0,0x30d40,0x24220} },
129 { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Chou #3", {0x1d4c0,0x395f8}, {0x0,0x0,0x1d4c0,0x395f8} },
130 { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Chou #4", {0x15f90,0x320c8}, {0x0,0x0,0x15f90,0x320c8} },
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 Postcard Rotated", {0x24220,0x186a0}, {0x0,0x0,0x24220,0x186a0} },
134 { SPOOLSS_FORM_BUILTIN, "Japanese Postcard", {0x186a0,0x24220}, {0x0,0x0,0x186a0,0x24220} },
135 { SPOOLSS_FORM_BUILTIN, "Ledger", {0x696b8,0x44368}, {0x0,0x0,0x696b8,0x44368} },
136 { SPOOLSS_FORM_BUILTIN, "Legal Extra", {0x3ae94,0x5d048}, {0x0,0x0,0x3ae94,0x5d048} },
137 { SPOOLSS_FORM_BUILTIN, "Legal", {0x34b5c,0x56d10}, {0x0,0x0,0x34b5c,0x56d10} },
138 { SPOOLSS_FORM_BUILTIN, "Letter Extra Transverse", {0x3ae94,0x4a6a0}, {0x0,0x0,0x3ae94,0x4a6a0} },
139 { SPOOLSS_FORM_BUILTIN, "Letter Extra", {0x3ae94,0x4a6a0}, {0x0,0x0,0x3ae94,0x4a6a0} },
140 { SPOOLSS_FORM_BUILTIN, "Letter Plus", {0x34b5c,0x4eb16}, {0x0,0x0,0x34b5c,0x4eb16} },
141 { SPOOLSS_FORM_BUILTIN, "Letter Rotated", {0x44368,0x34b5c}, {0x0,0x0,0x44368,0x34b5c} },
142 { SPOOLSS_FORM_BUILTIN, "Letter Small", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
143 { SPOOLSS_FORM_BUILTIN, "Letter Transverse", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
144 { SPOOLSS_FORM_BUILTIN, "Letter", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
145 { SPOOLSS_FORM_BUILTIN, "Note", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
146 { SPOOLSS_FORM_BUILTIN, "PRC 16K Rotated", {0x3f7a0,0x2de60}, {0x0,0x0,0x3f7a0,0x2de60} },
147 { SPOOLSS_FORM_BUILTIN, "PRC 16K", {0x2de60,0x3f7a0}, {0x0,0x0,0x2de60,0x3f7a0} },
148 { SPOOLSS_FORM_BUILTIN, "PRC 32K Rotated", {0x2cec0,0x1fbd0}, {0x0,0x0,0x2cec0,0x1fbd0} },
149 { SPOOLSS_FORM_BUILTIN, "PRC 32K", {0x1fbd0,0x2cec0}, {0x0,0x0,0x1fbd0,0x2cec0} },
150 { SPOOLSS_FORM_BUILTIN, "PRC 32K(Big) Rotated", {0x318f8,0x222e0}, {0x0,0x0,0x318f8,0x222e0} },
151 { SPOOLSS_FORM_BUILTIN, "PRC 32K(Big)", {0x222e0,0x318f8}, {0x0,0x0,0x222e0,0x318f8} },
152 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #1 Rotated", {0x28488,0x18e70}, {0x0,0x0,0x28488,0x18e70} },
153 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #1", {0x18e70,0x28488}, {0x0,0x0,0x18e70,0x28488} },
154 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #10 Rotated", {0x6fd10,0x4f1a0}, {0x0,0x0,0x6fd10,0x4f1a0} },
155 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #10", {0x4f1a0,0x6fd10}, {0x0,0x0,0x4f1a0,0x6fd10} },
156 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #2 Rotated", {0x2af80,0x18e70}, {0x0,0x0,0x2af80,0x18e70} },
157 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #2", {0x18e70,0x2af80}, {0x0,0x0,0x18e70,0x2af80} },
158 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #3 Rotated", {0x2af80,0x1e848}, {0x0,0x0,0x2af80,0x1e848} },
159 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #3", {0x1e848,0x2af80}, {0x0,0x0,0x1e848,0x2af80} },
160 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #4 Rotated", {0x32c80,0x1adb0}, {0x0,0x0,0x32c80,0x1adb0} },
161 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #4", {0x1adb0,0x32c80}, {0x0,0x0,0x1adb0,0x32c80} },
162 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #5 Rotated", {0x35b60,0x1adb0}, {0x0,0x0,0x35b60,0x1adb0} },
163 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #5", {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} },
164 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #6 Rotated", {0x38270,0x1d4c0}, {0x0,0x0,0x38270,0x1d4c0} },
165 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #6", {0x1d4c0,0x38270}, {0x0,0x0,0x1d4c0,0x38270} },
166 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #7 Rotated", {0x38270,0x27100}, {0x0,0x0,0x38270,0x27100} },
167 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #7", {0x27100,0x38270}, {0x0,0x0,0x27100,0x38270} },
168 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #8 Rotated", {0x4b708,0x1d4c0}, {0x0,0x0,0x4b708,0x1d4c0} },
169 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #8", {0x1d4c0,0x4b708}, {0x0,0x0,0x1d4c0,0x4b708} },
170 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #9 Rotated", {0x4f1a0,0x37e88}, {0x0,0x0,0x4f1a0,0x37e88} },
171 { SPOOLSS_FORM_BUILTIN, "PRC Envelope #9", {0x37e88,0x4f1a0}, {0x0,0x0,0x37e88,0x4f1a0} },
172 { SPOOLSS_FORM_BUILTIN, "Quarto", {0x347d8,0x43238}, {0x0,0x0,0x347d8,0x43238} },
173 { SPOOLSS_FORM_BUILTIN, "Reserved48", {0x1,0x1}, {0x0,0x0,0x1,0x1} },
174 { SPOOLSS_FORM_BUILTIN, "Reserved49", {0x1,0x1}, {0x0,0x0,0x1,0x1} },
175 { SPOOLSS_FORM_BUILTIN, "Statement", {0x221b4,0x34b5c}, {0x0,0x0,0x221b4,0x34b5c} },
176 { SPOOLSS_FORM_BUILTIN, "Super A", {0x376b8,0x56ea0}, {0x0,0x0,0x376b8,0x56ea0} },
177 { SPOOLSS_FORM_BUILTIN, "Super B", {0x4a768,0x76e58}, {0x0,0x0,0x4a768,0x76e58} },
178 { SPOOLSS_FORM_BUILTIN, "Tabloid Extra", {0x4a6a0,0x6f9f0}, {0x0,0x0,0x4a6a0,0x6f9f0} },
179 { SPOOLSS_FORM_BUILTIN, "Tabloid", {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} },
180 { SPOOLSS_FORM_BUILTIN, "US Std Fanfold", {0x5c3e1,0x44368}, {0x0,0x0,0x5c3e1,0x44368} }
183 /********************************************************************
184 static helper functions
185 ********************************************************************/
187 /****************************************************************************
188 Update the changeid time.
189 ****************************************************************************/
193 * @brief Update the ChangeID time of a printer.
195 * This is SO NASTY as some drivers need this to change, others need it
196 * static. This value will change every second, and I must hope that this
197 * is enough..... DON'T CHANGE THIS CODE WITHOUT A TEST MATRIX THE SIZE OF
200 * @return The ChangeID.
202 static uint32_t winreg_printer_rev_changeid(void)
206 get_process_uptime(&tv);
209 /* Return changeid as msec since spooler restart */
210 return tv.tv_sec * 1000 + tv.tv_usec / 1000;
213 * This setting seems to work well but is too untested
214 * to replace the above calculation. Left in for experimentation
215 * of the reader --jerry (Tue Mar 12 09:15:05 CST 2002)
217 return tv.tv_sec * 10 + tv.tv_usec / 100000;
224 * @brief Connect to the interal winreg server and open the given printer key.
226 * The function will create the needed subkeys if they don't exist.
228 * @param[in] mem_ctx The memory context to use.
230 * @param[in] session_info The supplied server info.
232 * @param[out] binding_handle A pointer for the winreg dcerpc binding handle.
234 * @param[in] path The path to the key to open.
236 * @param[in] key The key to open.
238 * @param[in] create_key Set to true if the key should be created if it
241 * @param[in] access_mask The access mask to open the key.
243 * @param[out] hive_handle A policy handle for the opened hive.
245 * @param[out] key_handle A policy handle for the opened key.
247 * @return WERR_OK on success, the corresponding DOS error
248 * code if something gone wrong.
250 static WERROR winreg_printer_openkey(TALLOC_CTX *mem_ctx,
251 const struct auth_serversupplied_info *session_info,
252 struct messaging_context *msg_ctx,
253 struct dcerpc_binding_handle **winreg_binding_handle,
257 uint32_t access_mask,
258 struct policy_handle *hive_handle,
259 struct policy_handle *key_handle)
261 struct tsocket_address *local;
262 struct dcerpc_binding_handle *binding_handle;
263 struct winreg_String wkey, wkeyclass;
266 WERROR result = WERR_OK;
269 rc = tsocket_address_inet_from_strings(mem_ctx,
278 status = rpcint_binding_handle(mem_ctx,
284 if (!NT_STATUS_IS_OK(status)) {
285 DEBUG(0, ("winreg_printer_openkey: Could not connect to winreg pipe: %s\n",
287 return ntstatus_to_werror(status);
290 status = dcerpc_winreg_OpenHKLM(binding_handle,
296 if (!NT_STATUS_IS_OK(status)) {
297 DEBUG(0, ("winreg_printer_openkey: Could not open HKLM hive: %s\n",
299 talloc_free(binding_handle);
300 return ntstatus_to_werror(status);
302 if (!W_ERROR_IS_OK(result)) {
303 DEBUG(0, ("winreg_printer_openkey: Could not open HKLM hive: %s\n",
304 win_errstr(result)));
305 talloc_free(binding_handle);
310 keyname = talloc_asprintf(mem_ctx, "%s\\%s", path, key);
312 keyname = talloc_strdup(mem_ctx, path);
314 if (keyname == NULL) {
315 talloc_free(binding_handle);
323 enum winreg_CreateAction action = REG_ACTION_NONE;
325 ZERO_STRUCT(wkeyclass);
328 status = dcerpc_winreg_CreateKey(binding_handle,
340 case REG_ACTION_NONE:
341 DEBUG(8, ("winreg_printer_openkey:createkey did nothing -- huh?\n"));
343 case REG_CREATED_NEW_KEY:
344 DEBUG(8, ("winreg_printer_openkey: createkey created %s\n", keyname));
346 case REG_OPENED_EXISTING_KEY:
347 DEBUG(8, ("winreg_printer_openkey: createkey opened existing %s\n", keyname));
351 status = dcerpc_winreg_OpenKey(binding_handle,
360 if (!NT_STATUS_IS_OK(status)) {
361 talloc_free(binding_handle);
362 return ntstatus_to_werror(status);
364 if (!W_ERROR_IS_OK(result)) {
365 talloc_free(binding_handle);
369 *winreg_binding_handle = binding_handle;
375 * @brief Create the registry keyname for the given printer.
377 * @param[in] mem_ctx The memory context to use.
379 * @param[in] printer The name of the printer to get the registry key.
381 * @return The registry key or NULL on error.
383 static char *winreg_printer_data_keyname(TALLOC_CTX *mem_ctx, const char *printer) {
384 return talloc_asprintf(mem_ctx, "%s\\%s", TOP_LEVEL_PRINT_PRINTERS_KEY, printer);
390 * @brief Enumerate values of an opened key handle and retrieve the data.
392 * @param[in] mem_ctx The memory context to use.
394 * @param[in] winreg_handle The binding handle for the rpc connection.
396 * @param[in] key_hnd The opened key handle.
398 * @param[out] pnum_values A pointer to store he number of values found.
400 * @param[out] pnum_values A pointer to store the number of values we found.
402 * @return WERR_OK on success, the corresponding DOS error
403 * code if something gone wrong.
405 static WERROR winreg_printer_enumvalues(TALLOC_CTX *mem_ctx,
406 struct dcerpc_binding_handle *winreg_handle,
407 struct policy_handle *key_hnd,
408 uint32_t *pnum_values,
409 struct spoolss_PrinterEnumValues **penum_values)
412 uint32_t num_subkeys, max_subkeylen, max_classlen;
413 uint32_t num_values, max_valnamelen, max_valbufsize;
414 uint32_t secdescsize;
416 NTTIME last_changed_time;
417 struct winreg_String classname;
419 struct spoolss_PrinterEnumValues *enum_values;
421 WERROR result = WERR_OK;
424 tmp_ctx = talloc_stackframe();
425 if (tmp_ctx == NULL) {
429 ZERO_STRUCT(classname);
431 status = dcerpc_winreg_QueryInfoKey(winreg_handle,
444 if (!NT_STATUS_IS_OK(status)) {
445 DEBUG(0, ("winreg_printer_enumvalues: Could not query info: %s\n",
447 result = ntstatus_to_werror(status);
450 if (!W_ERROR_IS_OK(result)) {
451 DEBUG(0, ("winreg_printer_enumvalues: Could not query info: %s\n",
452 win_errstr(result)));
456 if (num_values == 0) {
458 TALLOC_FREE(tmp_ctx);
462 enum_values = talloc_array(tmp_ctx, struct spoolss_PrinterEnumValues, num_values);
463 if (enum_values == NULL) {
468 for (i = 0; i < num_values; i++) {
469 struct spoolss_PrinterEnumValues val;
470 struct winreg_ValNameBuf name_buf;
471 enum winreg_Type type = REG_NONE;
478 name_buf.size = max_valnamelen + 2;
481 data_size = max_valbufsize;
484 data = (uint8_t *) talloc_zero_size(tmp_ctx, data_size);
488 status = dcerpc_winreg_EnumValue(winreg_handle,
495 data_size ? &data_size : NULL,
498 if (W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS) ) {
500 status = NT_STATUS_OK;
504 if (!NT_STATUS_IS_OK(status)) {
505 DEBUG(0, ("winreg_printer_enumvalues: Could not enumerate values: %s\n",
507 result = ntstatus_to_werror(status);
510 if (!W_ERROR_IS_OK(result)) {
511 DEBUG(0, ("winreg_printer_enumvalues: Could not enumerate values: %s\n",
512 win_errstr(result)));
516 if (name_buf.name == NULL) {
517 result = WERR_INVALID_PARAMETER;
521 val.value_name = talloc_strdup(enum_values, name_buf.name);
522 if (val.value_name == NULL) {
526 val.value_name_len = strlen_m_term(val.value_name) * 2;
529 val.data_length = length;
531 if (val.data_length) {
532 val.data = talloc(enum_values, DATA_BLOB);
533 if (val.data == NULL) {
537 *val.data = data_blob_talloc(val.data, data, val.data_length);
540 enum_values[i] = val;
543 *pnum_values = num_values;
545 *penum_values = talloc_move(mem_ctx, &enum_values);
551 TALLOC_FREE(tmp_ctx);
558 * @brief A function to delete a key and its subkeys recurively.
560 * @param[in] mem_ctx The memory context to use.
562 * @param[in] winreg_handle The binding handle for the rpc connection.
564 * @param[in] hive_handle A opened hive handle to the key.
566 * @param[in] access_mask The access mask to access the key.
568 * @param[in] key The key to delete
570 * @return WERR_OK on success, the corresponding DOS error
571 * code if something gone wrong.
573 static WERROR winreg_printer_delete_subkeys(TALLOC_CTX *mem_ctx,
574 struct dcerpc_binding_handle *winreg_handle,
575 struct policy_handle *hive_handle,
576 uint32_t access_mask,
579 const char **subkeys = NULL;
580 uint32_t num_subkeys = 0;
581 struct policy_handle key_hnd;
582 struct winreg_String wkey = { 0, };
583 WERROR result = WERR_OK;
587 ZERO_STRUCT(key_hnd);
590 DEBUG(2, ("winreg_printer_delete_subkeys: delete key %s\n", key));
592 status = dcerpc_winreg_OpenKey(winreg_handle,
600 if (!NT_STATUS_IS_OK(status)) {
601 DEBUG(0, ("winreg_printer_delete_subkeys: Could not open key %s: %s\n",
602 wkey.name, nt_errstr(status)));
603 return ntstatus_to_werror(status);
605 if (!W_ERROR_IS_OK(result)) {
606 DEBUG(0, ("winreg_printer_delete_subkeys: Could not open key %s: %s\n",
607 wkey.name, win_errstr(result)));
611 status = dcerpc_winreg_enum_keys(mem_ctx,
617 if (!NT_STATUS_IS_OK(status)) {
618 result = ntstatus_to_werror(status);
620 if (!W_ERROR_IS_OK(result)) {
624 for (i = 0; i < num_subkeys; i++) {
625 /* create key + subkey */
626 char *subkey = talloc_asprintf(mem_ctx, "%s\\%s", key, subkeys[i]);
627 if (subkey == NULL) {
631 DEBUG(2, ("winreg_printer_delete_subkeys: delete subkey %s\n", subkey));
632 result = winreg_printer_delete_subkeys(mem_ctx,
637 if (!W_ERROR_IS_OK(result)) {
642 if (is_valid_policy_hnd(&key_hnd)) {
644 dcerpc_winreg_CloseKey(winreg_handle, mem_ctx, &key_hnd, &ignore);
649 status = dcerpc_winreg_DeleteKey(winreg_handle,
654 if (!NT_STATUS_IS_OK(status)) {
655 result = ntstatus_to_werror(status);
659 if (is_valid_policy_hnd(&key_hnd)) {
662 dcerpc_winreg_CloseKey(winreg_handle, mem_ctx, &key_hnd, &ignore);
668 static WERROR winreg_printer_opendriver(TALLOC_CTX *mem_ctx,
669 const struct auth_serversupplied_info *session_info,
670 struct messaging_context *msg_ctx,
671 const char *drivername,
672 const char *architecture,
674 uint32_t access_mask,
676 struct dcerpc_binding_handle **winreg_binding_handle,
677 struct policy_handle *hive_hnd,
678 struct policy_handle *key_hnd)
683 key_name = talloc_asprintf(mem_ctx, "%s\\Environments\\%s\\Drivers\\Version-%u",
684 TOP_LEVEL_CONTROL_KEY,
685 architecture, version);
690 result = winreg_printer_openkey(mem_ctx,
693 winreg_binding_handle,
703 static WERROR winreg_enumval_to_dword(TALLOC_CTX *mem_ctx,
704 struct spoolss_PrinterEnumValues *v,
705 const char *valuename, uint32_t *dw)
707 /* just return if it is not the one we are looking for */
708 if (strcmp(valuename, v->value_name) != 0) {
709 return WERR_NOT_FOUND;
712 if (v->type != REG_DWORD) {
713 return WERR_INVALID_DATATYPE;
716 if (v->data_length != 4) {
721 *dw = IVAL(v->data->data, 0);
725 static WERROR winreg_enumval_to_sz(TALLOC_CTX *mem_ctx,
726 struct spoolss_PrinterEnumValues *v,
727 const char *valuename, const char **_str)
729 /* just return if it is not the one we are looking for */
730 if (strcmp(valuename, v->value_name) != 0) {
731 return WERR_NOT_FOUND;
734 if (v->type != REG_SZ) {
735 return WERR_INVALID_DATATYPE;
738 if (v->data_length == 0) {
739 *_str = talloc_strdup(mem_ctx, EMPTY_STRING);
746 if (!pull_reg_sz(mem_ctx, v->data, _str)) {
753 static WERROR winreg_enumval_to_multi_sz(TALLOC_CTX *mem_ctx,
754 struct spoolss_PrinterEnumValues *v,
755 const char *valuename,
758 /* just return if it is not the one we are looking for */
759 if (strcmp(valuename, v->value_name) != 0) {
760 return WERR_NOT_FOUND;
763 if (v->type != REG_MULTI_SZ) {
764 return WERR_INVALID_DATATYPE;
767 if (v->data_length == 0) {
768 *array = talloc_array(mem_ctx, const char *, 1);
769 if (*array == NULL) {
776 if (!pull_reg_multi_sz(mem_ctx, v->data, array)) {
783 static WERROR winreg_printer_write_date(TALLOC_CTX *mem_ctx,
784 struct dcerpc_binding_handle *winreg_handle,
785 struct policy_handle *key_handle,
789 struct winreg_String wvalue = { 0, };
791 WERROR result = WERR_OK;
798 str = talloc_strdup(mem_ctx, "01/01/1601");
800 t = nt_time_to_unix(data);
803 return map_werror_from_unix(errno);
805 str = talloc_asprintf(mem_ctx, "%02d/%02d/%04d",
806 tm->tm_mon + 1, tm->tm_mday, tm->tm_year + 1900);
813 if (!push_reg_sz(mem_ctx, &blob, str)) {
816 status = dcerpc_winreg_SetValue(winreg_handle,
824 if (!NT_STATUS_IS_OK(status)) {
825 result = ntstatus_to_werror(status);
827 if (!W_ERROR_IS_OK(result)) {
828 DEBUG(0, ("winreg_printer_write_date: Could not set value %s: %s\n",
829 wvalue.name, win_errstr(result)));
835 static WERROR winreg_printer_date_to_NTTIME(const char *str, NTTIME *data)
840 if (strequal(str, "01/01/1601")) {
847 if (sscanf(str, "%d/%d/%d",
848 &tm.tm_mon, &tm.tm_mday, &tm.tm_year) != 3) {
849 return WERR_INVALID_PARAMETER;
856 unix_to_nt_time(data, t);
861 static WERROR winreg_printer_write_ver(TALLOC_CTX *mem_ctx,
862 struct dcerpc_binding_handle *winreg_handle,
863 struct policy_handle *key_handle,
867 struct winreg_String wvalue = { 0, };
869 WERROR result = WERR_OK;
873 /* FIXME: check format is right,
874 * this needs to be something like: 6.1.7600.16385 */
875 str = talloc_asprintf(mem_ctx, "%u.%u.%u.%u",
876 (unsigned)((data >> 48) & 0xFFFF),
877 (unsigned)((data >> 32) & 0xFFFF),
878 (unsigned)((data >> 16) & 0xFFFF),
879 (unsigned)(data & 0xFFFF));
885 if (!push_reg_sz(mem_ctx, &blob, str)) {
888 status = dcerpc_winreg_SetValue(winreg_handle,
896 if (!NT_STATUS_IS_OK(status)) {
897 result = ntstatus_to_werror(status);
899 if (!W_ERROR_IS_OK(result)) {
900 DEBUG(0, ("winreg_printer_write_date: Could not set value %s: %s\n",
901 wvalue.name, win_errstr(result)));
907 static WERROR winreg_printer_ver_to_dword(const char *str, uint64_t *data)
909 unsigned int v1, v2, v3, v4;
911 if (sscanf(str, "%u.%u.%u.%u", &v1, &v2, &v3, &v4) != 4) {
912 return WERR_INVALID_PARAMETER;
915 *data = ((uint64_t)(v1 & 0xFFFF) << 48) +
916 ((uint64_t)(v2 & 0xFFFF) << 32) +
917 ((uint64_t)(v3 & 0xFFFF) << 16) +
918 (uint64_t)(v2 & 0xFFFF);
923 /********************************************************************
924 Public winreg function for spoolss
925 ********************************************************************/
927 WERROR winreg_create_printer(TALLOC_CTX *mem_ctx,
928 const struct auth_serversupplied_info *session_info,
929 struct messaging_context *msg_ctx,
930 const char *sharename)
932 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
933 struct dcerpc_binding_handle *winreg_handle = NULL;
934 struct policy_handle hive_hnd, key_hnd;
935 struct spoolss_SetPrinterInfo2 *info2;
936 struct security_descriptor *secdesc;
937 struct winreg_String wkey, wkeyclass;
939 const char *subkeys[] = { SPOOL_DSDRIVER_KEY, SPOOL_DSSPOOLER_KEY, SPOOL_PRINTERDATA_KEY };
940 uint32_t i, count = ARRAY_SIZE(subkeys);
941 uint32_t info2_mask = 0;
942 WERROR result = WERR_OK;
945 tmp_ctx = talloc_stackframe();
946 if (tmp_ctx == NULL) {
950 path = winreg_printer_data_keyname(tmp_ctx, sharename);
952 TALLOC_FREE(tmp_ctx);
956 ZERO_STRUCT(hive_hnd);
957 ZERO_STRUCT(key_hnd);
959 result = winreg_printer_openkey(tmp_ctx,
969 if (W_ERROR_IS_OK(result)) {
970 DEBUG(2, ("winreg_create_printer: Skipping, %s already exists\n", path));
972 } else if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
973 DEBUG(2, ("winreg_create_printer: Creating default values in %s\n", path));
974 } else if (!W_ERROR_IS_OK(result)) {
975 DEBUG(0, ("winreg_create_printer: Could not open key %s: %s\n",
976 path, win_errstr(result)));
980 /* Create the main key */
981 result = winreg_printer_openkey(tmp_ctx,
991 if (!W_ERROR_IS_OK(result)) {
992 DEBUG(0, ("winreg_create_printer_keys: Could not create key %s: %s\n",
993 path, win_errstr(result)));
997 if (is_valid_policy_hnd(&key_hnd)) {
998 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &result);
1001 /* Create subkeys */
1002 for (i = 0; i < count; i++) {
1004 enum winreg_CreateAction action = REG_ACTION_NONE;
1006 ZERO_STRUCT(key_hnd);
1009 wkey.name = talloc_asprintf(tmp_ctx, "%s\\%s", path, subkeys[i]);
1010 if (wkey.name == NULL) {
1011 result = WERR_NOMEM;
1015 ZERO_STRUCT(wkeyclass);
1016 wkeyclass.name = "";
1018 status = dcerpc_winreg_CreateKey(winreg_handle,
1029 if (!NT_STATUS_IS_OK(status)) {
1030 result = ntstatus_to_werror(status);
1032 if (!W_ERROR_IS_OK(result)) {
1033 DEBUG(0, ("winreg_create_printer_keys: Could not create key %s: %s\n",
1034 wkey.name, win_errstr(result)));
1038 if (strequal(subkeys[i], SPOOL_DSSPOOLER_KEY)) {
1039 const char *dnssuffix;
1040 const char *longname;
1041 const char *uncname;
1043 status = dcerpc_winreg_set_sz(tmp_ctx,
1046 SPOOL_REG_PRINTERNAME,
1049 if (!NT_STATUS_IS_OK(status)) {
1050 result = ntstatus_to_werror(status);
1052 if (!W_ERROR_IS_OK(result)) {
1056 status = dcerpc_winreg_set_sz(tmp_ctx,
1059 SPOOL_REG_SHORTSERVERNAME,
1062 if (!NT_STATUS_IS_OK(status)) {
1063 result = ntstatus_to_werror(status);
1065 if (!W_ERROR_IS_OK(result)) {
1069 /* We make the assumption that the netbios name
1070 * is the same as the DNS name since the former
1071 * will be what we used to join the domain
1073 dnssuffix = get_mydnsdomname(tmp_ctx);
1074 if (dnssuffix != NULL && dnssuffix[0] != '\0') {
1075 longname = talloc_asprintf(tmp_ctx, "%s.%s", lp_netbios_name(), dnssuffix);
1077 longname = talloc_strdup(tmp_ctx, lp_netbios_name());
1079 if (longname == NULL) {
1080 result = WERR_NOMEM;
1084 status = dcerpc_winreg_set_sz(tmp_ctx,
1087 SPOOL_REG_SERVERNAME,
1090 if (!NT_STATUS_IS_OK(status)) {
1091 result = ntstatus_to_werror(status);
1093 if (!W_ERROR_IS_OK(result)) {
1097 uncname = talloc_asprintf(tmp_ctx, "\\\\%s\\%s",
1098 longname, sharename);
1099 if (uncname == NULL) {
1100 result = WERR_NOMEM;
1104 status = dcerpc_winreg_set_sz(tmp_ctx,
1110 if (!NT_STATUS_IS_OK(status)) {
1111 result = ntstatus_to_werror(status);
1113 if (!W_ERROR_IS_OK(result)) {
1117 status = dcerpc_winreg_set_dword(tmp_ctx,
1120 SPOOL_REG_VERSIONNUMBER,
1123 if (!NT_STATUS_IS_OK(status)) {
1124 result = ntstatus_to_werror(status);
1126 if (!W_ERROR_IS_OK(result)) {
1130 status = dcerpc_winreg_set_dword(tmp_ctx,
1133 SPOOL_REG_PRINTSTARTTIME,
1136 if (!NT_STATUS_IS_OK(status)) {
1137 result = ntstatus_to_werror(status);
1139 if (!W_ERROR_IS_OK(result)) {
1143 status = dcerpc_winreg_set_dword(tmp_ctx,
1146 SPOOL_REG_PRINTENDTIME,
1149 if (!NT_STATUS_IS_OK(status)) {
1150 result = ntstatus_to_werror(status);
1152 if (!W_ERROR_IS_OK(result)) {
1156 status = dcerpc_winreg_set_dword(tmp_ctx,
1162 if (!NT_STATUS_IS_OK(status)) {
1163 result = ntstatus_to_werror(status);
1165 if (!W_ERROR_IS_OK(result)) {
1169 status = dcerpc_winreg_set_dword(tmp_ctx,
1172 SPOOL_REG_PRINTKEEPPRINTEDJOBS,
1175 if (!NT_STATUS_IS_OK(status)) {
1176 result = ntstatus_to_werror(status);
1178 if (!W_ERROR_IS_OK(result)) {
1183 if (is_valid_policy_hnd(&key_hnd)) {
1184 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &result);
1187 info2 = talloc_zero(tmp_ctx, struct spoolss_SetPrinterInfo2);
1188 if (info2 == NULL) {
1189 result = WERR_NOMEM;
1193 info2->printername = sharename;
1194 if (info2->printername == NULL) {
1195 result = WERR_NOMEM;
1198 info2_mask |= SPOOLSS_PRINTER_INFO_PRINTERNAME;
1200 info2->sharename = sharename;
1201 info2_mask |= SPOOLSS_PRINTER_INFO_SHARENAME;
1203 info2->portname = SAMBA_PRINTER_PORT_NAME;
1204 info2_mask |= SPOOLSS_PRINTER_INFO_PORTNAME;
1206 info2->printprocessor = "winprint";
1207 info2_mask |= SPOOLSS_PRINTER_INFO_PRINTPROCESSOR;
1209 info2->datatype = "RAW";
1210 info2_mask |= SPOOLSS_PRINTER_INFO_DATATYPE;
1212 info2->comment = "";
1213 info2_mask |= SPOOLSS_PRINTER_INFO_COMMENT;
1215 info2->attributes = PRINTER_ATTRIBUTE_SAMBA;
1216 info2_mask |= SPOOLSS_PRINTER_INFO_ATTRIBUTES;
1218 info2->starttime = 0; /* Minutes since 12:00am GMT */
1219 info2_mask |= SPOOLSS_PRINTER_INFO_STARTTIME;
1221 info2->untiltime = 0; /* Minutes since 12:00am GMT */
1222 info2_mask |= SPOOLSS_PRINTER_INFO_UNTILTIME;
1224 info2->priority = 1;
1225 info2_mask |= SPOOLSS_PRINTER_INFO_PRIORITY;
1227 info2->defaultpriority = 1;
1228 info2_mask |= SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY;
1230 result = spoolss_create_default_secdesc(tmp_ctx, &secdesc);
1231 if (!W_ERROR_IS_OK(result)) {
1234 info2_mask |= SPOOLSS_PRINTER_INFO_SECDESC;
1237 * Don't write a default Device Mode to the registry! The Device Mode is
1238 * only written to disk with a SetPrinter level 2 or 8.
1241 result = winreg_update_printer(tmp_ctx,
1251 if (winreg_handle != NULL) {
1254 if (is_valid_policy_hnd(&key_hnd)) {
1255 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
1257 if (is_valid_policy_hnd(&hive_hnd)) {
1258 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
1262 talloc_free(tmp_ctx);
1266 WERROR winreg_update_printer(TALLOC_CTX *mem_ctx,
1267 const struct auth_serversupplied_info *session_info,
1268 struct messaging_context *msg_ctx,
1269 const char *sharename,
1270 uint32_t info2_mask,
1271 struct spoolss_SetPrinterInfo2 *info2,
1272 struct spoolss_DeviceMode *devmode,
1273 struct security_descriptor *secdesc)
1275 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1276 struct dcerpc_binding_handle *winreg_handle = NULL;
1277 struct policy_handle hive_hnd, key_hnd;
1278 int snum = lp_servicenumber(sharename);
1279 enum ndr_err_code ndr_err;
1282 WERROR result = WERR_OK;
1284 TALLOC_CTX *tmp_ctx;
1286 tmp_ctx = talloc_stackframe();
1287 if (tmp_ctx == NULL) {
1291 path = winreg_printer_data_keyname(tmp_ctx, sharename);
1293 TALLOC_FREE(tmp_ctx);
1297 ZERO_STRUCT(hive_hnd);
1298 ZERO_STRUCT(key_hnd);
1300 result = winreg_printer_openkey(tmp_ctx,
1310 if (!W_ERROR_IS_OK(result)) {
1311 DEBUG(0, ("winreg_update_printer: Could not open key %s: %s\n",
1312 path, win_errstr(result)));
1316 if (info2_mask & SPOOLSS_PRINTER_INFO_ATTRIBUTES) {
1317 status = dcerpc_winreg_set_dword(tmp_ctx,
1323 if (!NT_STATUS_IS_OK(status)) {
1324 result = ntstatus_to_werror(status);
1326 if (!W_ERROR_IS_OK(result)) {
1332 if (info2_mask & SPOOLSS_PRINTER_INFO_AVERAGEPPM) {
1333 status = dcerpc_winreg_set_dword(tmp_ctx,
1339 if (!NT_STATUS_IS_OK(status)) {
1340 result = ntstatus_to_werror(status);
1342 if (!W_ERROR_IS_OK(result)) {
1348 if (info2_mask & SPOOLSS_PRINTER_INFO_COMMENT) {
1349 status = dcerpc_winreg_set_sz(tmp_ctx,
1355 if (!NT_STATUS_IS_OK(status)) {
1356 result = ntstatus_to_werror(status);
1358 if (!W_ERROR_IS_OK(result)) {
1363 if (info2_mask & SPOOLSS_PRINTER_INFO_DATATYPE) {
1364 status = dcerpc_winreg_set_sz(tmp_ctx,
1370 if (!NT_STATUS_IS_OK(status)) {
1371 result = ntstatus_to_werror(status);
1373 if (!W_ERROR_IS_OK(result)) {
1378 if (info2_mask & SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY) {
1379 status = dcerpc_winreg_set_dword(tmp_ctx,
1383 info2->defaultpriority,
1385 if (!NT_STATUS_IS_OK(status)) {
1386 result = ntstatus_to_werror(status);
1388 if (!W_ERROR_IS_OK(result)) {
1393 if (info2_mask & SPOOLSS_PRINTER_INFO_DEVMODE) {
1395 * Some client drivers freak out if there is a NULL devmode
1396 * (probably the driver is not checking before accessing
1397 * the devmode pointer) --jerry
1399 if (devmode == NULL && lp_default_devmode(snum) && info2 != NULL) {
1400 result = spoolss_create_default_devmode(tmp_ctx,
1403 if (!W_ERROR_IS_OK(result)) {
1408 if (devmode->size != (ndr_size_spoolss_DeviceMode(devmode, 0) - devmode->__driverextra_length)) {
1409 result = WERR_INVALID_PARAM;
1413 ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, devmode,
1414 (ndr_push_flags_fn_t) ndr_push_spoolss_DeviceMode);
1415 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1416 DEBUG(0, ("winreg_update_printer: Failed to marshall device mode\n"));
1417 result = WERR_NOMEM;
1421 status = dcerpc_winreg_set_binary(tmp_ctx,
1427 if (!NT_STATUS_IS_OK(status)) {
1428 result = ntstatus_to_werror(status);
1430 if (!W_ERROR_IS_OK(result)) {
1435 if (info2_mask & SPOOLSS_PRINTER_INFO_DRIVERNAME) {
1436 status = dcerpc_winreg_set_sz(tmp_ctx,
1442 if (!NT_STATUS_IS_OK(status)) {
1443 result = ntstatus_to_werror(status);
1445 if (!W_ERROR_IS_OK(result)) {
1450 if (info2_mask & SPOOLSS_PRINTER_INFO_LOCATION) {
1451 status = dcerpc_winreg_set_sz(tmp_ctx,
1457 if (!NT_STATUS_IS_OK(status)) {
1458 result = ntstatus_to_werror(status);
1460 if (!W_ERROR_IS_OK(result)) {
1465 if (info2_mask & SPOOLSS_PRINTER_INFO_PARAMETERS) {
1466 status = dcerpc_winreg_set_sz(tmp_ctx,
1472 if (!NT_STATUS_IS_OK(status)) {
1473 result = ntstatus_to_werror(status);
1475 if (!W_ERROR_IS_OK(result)) {
1480 if (info2_mask & SPOOLSS_PRINTER_INFO_PORTNAME) {
1481 status = dcerpc_winreg_set_sz(tmp_ctx,
1487 if (!NT_STATUS_IS_OK(status)) {
1488 result = ntstatus_to_werror(status);
1490 if (!W_ERROR_IS_OK(result)) {
1495 if (info2_mask & SPOOLSS_PRINTER_INFO_PRINTERNAME) {
1497 * in addprinter: no servername and the printer is the name
1498 * in setprinter: servername is \\server
1499 * and printer is \\server\\printer
1501 * Samba manages only local printers.
1502 * we currently don't support things like i
1503 * path=\\other_server\printer
1505 * We only store the printername, not \\server\printername
1507 const char *p = strrchr(info2->printername, '\\');
1509 p = info2->printername;
1513 status = dcerpc_winreg_set_sz(tmp_ctx,
1519 if (!NT_STATUS_IS_OK(status)) {
1520 result = ntstatus_to_werror(status);
1522 if (!W_ERROR_IS_OK(result)) {
1527 if (info2_mask & SPOOLSS_PRINTER_INFO_PRINTPROCESSOR) {
1528 status = dcerpc_winreg_set_sz(tmp_ctx,
1532 info2->printprocessor,
1534 if (!NT_STATUS_IS_OK(status)) {
1535 result = ntstatus_to_werror(status);
1537 if (!W_ERROR_IS_OK(result)) {
1542 if (info2_mask & SPOOLSS_PRINTER_INFO_PRIORITY) {
1543 status = dcerpc_winreg_set_dword(tmp_ctx,
1549 if (!NT_STATUS_IS_OK(status)) {
1550 result = ntstatus_to_werror(status);
1552 if (!W_ERROR_IS_OK(result)) {
1557 if (info2_mask & SPOOLSS_PRINTER_INFO_SECDESC) {
1559 * We need a security descriptor, if it isn't specified by
1560 * AddPrinter{Ex} then create a default descriptor.
1562 if (secdesc == NULL) {
1563 result = spoolss_create_default_secdesc(tmp_ctx, &secdesc);
1564 if (!W_ERROR_IS_OK(result)) {
1568 result = winreg_set_printer_secdesc(tmp_ctx,
1573 if (!W_ERROR_IS_OK(result)) {
1578 if (info2_mask & SPOOLSS_PRINTER_INFO_SEPFILE) {
1579 status = dcerpc_winreg_set_sz(tmp_ctx,
1585 if (!NT_STATUS_IS_OK(status)) {
1586 result = ntstatus_to_werror(status);
1588 if (!W_ERROR_IS_OK(result)) {
1593 if (info2_mask & SPOOLSS_PRINTER_INFO_SHARENAME) {
1594 status = dcerpc_winreg_set_sz(tmp_ctx,
1600 if (!NT_STATUS_IS_OK(status)) {
1601 result = ntstatus_to_werror(status);
1603 if (!W_ERROR_IS_OK(result)) {
1608 if (info2_mask & SPOOLSS_PRINTER_INFO_STARTTIME) {
1609 status = dcerpc_winreg_set_dword(tmp_ctx,
1615 if (!NT_STATUS_IS_OK(status)) {
1616 result = ntstatus_to_werror(status);
1618 if (!W_ERROR_IS_OK(result)) {
1623 if (info2_mask & SPOOLSS_PRINTER_INFO_STATUS) {
1624 status = dcerpc_winreg_set_dword(tmp_ctx,
1630 if (!NT_STATUS_IS_OK(status)) {
1631 result = ntstatus_to_werror(status);
1633 if (!W_ERROR_IS_OK(result)) {
1638 if (info2_mask & SPOOLSS_PRINTER_INFO_UNTILTIME) {
1639 status = dcerpc_winreg_set_dword(tmp_ctx,
1645 if (!NT_STATUS_IS_OK(status)) {
1646 result = ntstatus_to_werror(status);
1648 if (!W_ERROR_IS_OK(result)) {
1653 status = dcerpc_winreg_set_dword(tmp_ctx,
1657 winreg_printer_rev_changeid(),
1659 if (!NT_STATUS_IS_OK(status)) {
1660 result = ntstatus_to_werror(status);
1662 if (!W_ERROR_IS_OK(result)) {
1668 if (winreg_handle != NULL) {
1671 if (is_valid_policy_hnd(&key_hnd)) {
1672 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
1674 if (is_valid_policy_hnd(&hive_hnd)) {
1675 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
1679 TALLOC_FREE(tmp_ctx);
1683 WERROR winreg_get_printer(TALLOC_CTX *mem_ctx,
1684 const struct auth_serversupplied_info *session_info,
1685 struct messaging_context *msg_ctx,
1686 const char *printer,
1687 struct spoolss_PrinterInfo2 **pinfo2)
1689 struct spoolss_PrinterInfo2 *info2;
1690 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1691 struct dcerpc_binding_handle *winreg_handle = NULL;
1692 struct policy_handle hive_hnd, key_hnd;
1693 struct spoolss_PrinterEnumValues *enum_values = NULL;
1694 struct spoolss_PrinterEnumValues *v = NULL;
1695 enum ndr_err_code ndr_err;
1697 int snum = lp_servicenumber(printer);
1698 uint32_t num_values = 0;
1702 WERROR result = WERR_OK;
1703 TALLOC_CTX *tmp_ctx;
1705 tmp_ctx = talloc_stackframe();
1706 if (tmp_ctx == NULL) {
1710 path = winreg_printer_data_keyname(tmp_ctx, printer);
1712 TALLOC_FREE(tmp_ctx);
1716 result = winreg_printer_openkey(tmp_ctx,
1726 if (!W_ERROR_IS_OK(result)) {
1727 DEBUG(2, ("winreg_get_printer: Could not open key %s: %s\n",
1728 path, win_errstr(result)));
1732 result = winreg_printer_enumvalues(tmp_ctx,
1737 if (!W_ERROR_IS_OK(result)) {
1738 DEBUG(0, ("winreg_get_printer: Could not enumerate values in %s: %s\n",
1739 path, win_errstr(result)));
1743 info2 = talloc_zero(tmp_ctx, struct spoolss_PrinterInfo2);
1744 if (info2 == NULL) {
1745 result = WERR_NOMEM;
1749 FILL_STRING(info2, EMPTY_STRING, info2->servername);
1750 FILL_STRING(info2, EMPTY_STRING, info2->printername);
1751 FILL_STRING(info2, EMPTY_STRING, info2->sharename);
1752 FILL_STRING(info2, EMPTY_STRING, info2->portname);
1753 FILL_STRING(info2, EMPTY_STRING, info2->drivername);
1754 FILL_STRING(info2, EMPTY_STRING, info2->comment);
1755 FILL_STRING(info2, EMPTY_STRING, info2->location);
1756 FILL_STRING(info2, EMPTY_STRING, info2->sepfile);
1757 FILL_STRING(info2, EMPTY_STRING, info2->printprocessor);
1758 FILL_STRING(info2, EMPTY_STRING, info2->datatype);
1759 FILL_STRING(info2, EMPTY_STRING, info2->parameters);
1761 for (i = 0; i < num_values; i++) {
1762 v = &enum_values[i];
1764 result = winreg_enumval_to_sz(info2,
1767 &info2->printername);
1768 CHECK_ERROR(result);
1770 result = winreg_enumval_to_sz(info2,
1774 CHECK_ERROR(result);
1776 result = winreg_enumval_to_sz(info2,
1780 CHECK_ERROR(result);
1782 result = winreg_enumval_to_sz(info2,
1786 CHECK_ERROR(result);
1788 result = winreg_enumval_to_sz(info2,
1792 CHECK_ERROR(result);
1794 result = winreg_enumval_to_sz(info2,
1798 CHECK_ERROR(result);
1800 result = winreg_enumval_to_sz(info2,
1803 &info2->printprocessor);
1804 CHECK_ERROR(result);
1806 result = winreg_enumval_to_sz(info2,
1810 CHECK_ERROR(result);
1812 result = winreg_enumval_to_sz(info2,
1815 &info2->parameters);
1816 CHECK_ERROR(result);
1818 result = winreg_enumval_to_sz(info2,
1821 &info2->drivername);
1822 CHECK_ERROR(result);
1824 result = winreg_enumval_to_dword(info2,
1827 &info2->attributes);
1828 CHECK_ERROR(result);
1830 result = winreg_enumval_to_dword(info2,
1834 CHECK_ERROR(result);
1836 result = winreg_enumval_to_dword(info2,
1839 &info2->defaultpriority);
1840 CHECK_ERROR(result);
1842 result = winreg_enumval_to_dword(info2,
1846 CHECK_ERROR(result);
1848 result = winreg_enumval_to_dword(info2,
1852 CHECK_ERROR(result);
1854 result = winreg_enumval_to_dword(info2,
1858 CHECK_ERROR(result);
1860 result = winreg_enumval_to_dword(info2,
1864 CHECK_ERROR(result);
1867 if (!W_ERROR_IS_OK(result)) {
1868 DEBUG(0, ("winreg_get_printer: winreg_enumval_to_TYPE() failed "
1871 win_errstr(result)));
1875 /* Construct the Device Mode */
1876 status = dcerpc_winreg_query_binary(tmp_ctx,
1882 if (!NT_STATUS_IS_OK(status)) {
1883 result = ntstatus_to_werror(status);
1885 if (W_ERROR_IS_OK(result)) {
1886 info2->devmode = talloc_zero(info2, struct spoolss_DeviceMode);
1887 if (info2->devmode == NULL) {
1888 result = WERR_NOMEM;
1891 ndr_err = ndr_pull_struct_blob(&blob,
1894 (ndr_pull_flags_fn_t) ndr_pull_spoolss_DeviceMode);
1895 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1896 DEBUG(0, ("winreg_get_printer: Failed to unmarshall device mode\n"));
1897 result = WERR_NOMEM;
1902 if (info2->devmode == NULL && lp_default_devmode(snum)) {
1903 result = spoolss_create_default_devmode(info2,
1906 if (!W_ERROR_IS_OK(result)) {
1911 if (info2->devmode) {
1912 info2->devmode->size = ndr_size_spoolss_DeviceMode(info2->devmode, 0) - info2->devmode->driverextra_data.length;
1915 result = winreg_get_printer_secdesc(info2,
1920 if (!W_ERROR_IS_OK(result)) {
1924 /* Fix for OS/2 drivers. */
1925 if (get_remote_arch() == RA_OS2) {
1926 spoolss_map_to_os2_driver(info2, &info2->drivername);
1930 *pinfo2 = talloc_move(mem_ctx, &info2);
1935 if (winreg_handle != NULL) {
1938 if (is_valid_policy_hnd(&key_hnd)) {
1939 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
1941 if (is_valid_policy_hnd(&hive_hnd)) {
1942 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
1946 TALLOC_FREE(tmp_ctx);
1950 WERROR winreg_get_printer_secdesc(TALLOC_CTX *mem_ctx,
1951 const struct auth_serversupplied_info *session_info,
1952 struct messaging_context *msg_ctx,
1953 const char *sharename,
1954 struct spoolss_security_descriptor **psecdesc)
1956 struct spoolss_security_descriptor *secdesc;
1957 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1958 struct dcerpc_binding_handle *winreg_handle = NULL;
1959 struct policy_handle hive_hnd, key_hnd;
1961 TALLOC_CTX *tmp_ctx;
1965 tmp_ctx = talloc_stackframe();
1966 if (tmp_ctx == NULL) {
1970 path = winreg_printer_data_keyname(tmp_ctx, sharename);
1972 talloc_free(tmp_ctx);
1976 ZERO_STRUCT(hive_hnd);
1977 ZERO_STRUCT(key_hnd);
1979 result = winreg_printer_openkey(tmp_ctx,
1989 if (!W_ERROR_IS_OK(result)) {
1990 if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
1991 goto create_default;
1996 status = dcerpc_winreg_query_sd(tmp_ctx,
2002 if (!NT_STATUS_IS_OK(status)) {
2003 result = ntstatus_to_werror(status);
2005 if (!W_ERROR_IS_OK(result)) {
2006 if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
2007 goto create_default;
2013 *psecdesc = talloc_move(mem_ctx, &secdesc);
2020 result = winreg_printer_openkey(tmp_ctx,
2030 if (!W_ERROR_IS_OK(result)) {
2034 result = spoolss_create_default_secdesc(tmp_ctx, &secdesc);
2035 if (!W_ERROR_IS_OK(result)) {
2039 /* If security descriptor is owned by S-1-1-0 and winbindd is up,
2040 this security descriptor has been created when winbindd was
2041 down. Take ownership of security descriptor. */
2042 if (dom_sid_equal(secdesc->owner_sid, &global_sid_World)) {
2043 struct dom_sid owner_sid;
2045 /* Change sd owner to workgroup administrator */
2047 if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid)) {
2048 struct spoolss_security_descriptor *new_secdesc;
2052 sid_append_rid(&owner_sid, DOMAIN_RID_ADMINISTRATOR);
2054 new_secdesc = make_sec_desc(tmp_ctx,
2063 if (new_secdesc == NULL) {
2064 result = WERR_NOMEM;
2068 /* Swap with other one */
2069 secdesc = new_secdesc;
2073 status = dcerpc_winreg_set_sd(tmp_ctx,
2079 if (!NT_STATUS_IS_OK(status)) {
2080 result = ntstatus_to_werror(status);
2082 if (!W_ERROR_IS_OK(result)) {
2087 *psecdesc = talloc_move(mem_ctx, &secdesc);
2092 if (winreg_handle != NULL) {
2095 if (is_valid_policy_hnd(&key_hnd)) {
2096 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
2098 if (is_valid_policy_hnd(&hive_hnd)) {
2099 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
2103 talloc_free(tmp_ctx);
2107 WERROR winreg_set_printer_secdesc(TALLOC_CTX *mem_ctx,
2108 const struct auth_serversupplied_info *session_info,
2109 struct messaging_context *msg_ctx,
2110 const char *sharename,
2111 const struct spoolss_security_descriptor *secdesc)
2113 const struct spoolss_security_descriptor *new_secdesc = secdesc;
2114 struct spoolss_security_descriptor *old_secdesc;
2115 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2116 struct dcerpc_binding_handle *winreg_handle = NULL;
2117 struct policy_handle hive_hnd, key_hnd;
2119 TALLOC_CTX *tmp_ctx;
2123 tmp_ctx = talloc_stackframe();
2124 if (tmp_ctx == NULL) {
2128 path = winreg_printer_data_keyname(tmp_ctx, sharename);
2130 talloc_free(tmp_ctx);
2135 * The old owner and group sids of the security descriptor are not
2136 * present when new ACEs are added or removed by changing printer
2137 * permissions through NT. If they are NULL in the new security
2138 * descriptor then copy them over from the old one.
2140 if (!secdesc->owner_sid || !secdesc->group_sid) {
2141 struct dom_sid *owner_sid, *group_sid;
2142 struct security_acl *dacl, *sacl;
2145 result = winreg_get_printer_secdesc(tmp_ctx,
2150 if (!W_ERROR_IS_OK(result)) {
2151 talloc_free(tmp_ctx);
2155 /* Pick out correct owner and group sids */
2156 owner_sid = secdesc->owner_sid ?
2157 secdesc->owner_sid :
2158 old_secdesc->owner_sid;
2160 group_sid = secdesc->group_sid ?
2161 secdesc->group_sid :
2162 old_secdesc->group_sid;
2164 dacl = secdesc->dacl ?
2168 sacl = secdesc->sacl ?
2172 /* Make a deep copy of the security descriptor */
2173 new_secdesc = make_sec_desc(tmp_ctx,
2181 if (new_secdesc == NULL) {
2182 talloc_free(tmp_ctx);
2187 ZERO_STRUCT(hive_hnd);
2188 ZERO_STRUCT(key_hnd);
2190 result = winreg_printer_openkey(tmp_ctx,
2200 if (!W_ERROR_IS_OK(result)) {
2204 status = dcerpc_winreg_set_sd(tmp_ctx,
2210 if (!NT_STATUS_IS_OK(status)) {
2211 result = ntstatus_to_werror(status);
2215 if (winreg_handle != NULL) {
2218 if (is_valid_policy_hnd(&key_hnd)) {
2219 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
2221 if (is_valid_policy_hnd(&hive_hnd)) {
2222 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
2226 talloc_free(tmp_ctx);
2230 /* Set printer data over the winreg pipe. */
2231 WERROR winreg_set_printer_dataex(TALLOC_CTX *mem_ctx,
2232 const struct auth_serversupplied_info *session_info,
2233 struct messaging_context *msg_ctx,
2234 const char *printer,
2237 enum winreg_Type type,
2241 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2242 struct dcerpc_binding_handle *winreg_handle = NULL;
2243 struct policy_handle hive_hnd, key_hnd;
2244 struct winreg_String wvalue = { 0, };
2246 WERROR result = WERR_OK;
2248 TALLOC_CTX *tmp_ctx;
2250 tmp_ctx = talloc_stackframe();
2251 if (tmp_ctx == NULL) {
2255 path = winreg_printer_data_keyname(tmp_ctx, printer);
2257 TALLOC_FREE(tmp_ctx);
2261 ZERO_STRUCT(hive_hnd);
2262 ZERO_STRUCT(key_hnd);
2264 DEBUG(8, ("winreg_set_printer_dataex: Open printer key %s, value %s, access_mask: 0x%05x for [%s]\n",
2265 key, value, access_mask, printer));
2266 result = winreg_printer_openkey(tmp_ctx,
2276 if (!W_ERROR_IS_OK(result)) {
2277 DEBUG(0, ("winreg_set_printer_dataex: Could not open key %s: %s\n",
2278 key, win_errstr(result)));
2282 wvalue.name = value;
2283 status = dcerpc_winreg_SetValue(winreg_handle,
2291 if (!NT_STATUS_IS_OK(status)) {
2292 DEBUG(0, ("winreg_set_printer_dataex: Could not set value %s: %s\n",
2293 value, nt_errstr(status)));
2294 result = ntstatus_to_werror(status);
2298 if (winreg_handle != NULL) {
2301 if (is_valid_policy_hnd(&key_hnd)) {
2302 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
2304 if (is_valid_policy_hnd(&hive_hnd)) {
2305 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
2309 TALLOC_FREE(tmp_ctx);
2313 /* Get printer data over a winreg pipe. */
2314 WERROR winreg_get_printer_dataex(TALLOC_CTX *mem_ctx,
2315 const struct auth_serversupplied_info *session_info,
2316 struct messaging_context *msg_ctx,
2317 const char *printer,
2320 enum winreg_Type *type,
2322 uint32_t *data_size)
2324 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2325 struct dcerpc_binding_handle *winreg_handle = NULL;
2326 struct policy_handle hive_hnd, key_hnd;
2327 struct winreg_String wvalue;
2328 enum winreg_Type type_in = REG_NONE;
2330 uint8_t *data_in = NULL;
2331 uint32_t data_in_size = 0;
2332 uint32_t value_len = 0;
2333 WERROR result = WERR_OK;
2335 TALLOC_CTX *tmp_ctx;
2337 tmp_ctx = talloc_stackframe();
2338 if (tmp_ctx == NULL) {
2342 path = winreg_printer_data_keyname(tmp_ctx, printer);
2344 TALLOC_FREE(tmp_ctx);
2348 ZERO_STRUCT(hive_hnd);
2349 ZERO_STRUCT(key_hnd);
2351 result = winreg_printer_openkey(tmp_ctx,
2361 if (!W_ERROR_IS_OK(result)) {
2362 DEBUG(2, ("winreg_get_printer_dataex: Could not open key %s: %s\n",
2363 key, win_errstr(result)));
2367 wvalue.name = value;
2370 * call QueryValue once with data == NULL to get the
2371 * needed memory size to be allocated, then allocate
2372 * data buffer and call again.
2374 status = dcerpc_winreg_QueryValue(winreg_handle,
2383 if (!NT_STATUS_IS_OK(status)) {
2384 DEBUG(0, ("winreg_get_printer_dataex: Could not query value %s: %s\n",
2385 value, nt_errstr(status)));
2386 result = ntstatus_to_werror(status);
2389 if (!W_ERROR_IS_OK(result)) {
2393 data_in = (uint8_t *) TALLOC(tmp_ctx, data_in_size);
2394 if (data_in == NULL) {
2395 result = WERR_NOMEM;
2400 status = dcerpc_winreg_QueryValue(winreg_handle,
2409 if (!NT_STATUS_IS_OK(status)) {
2410 DEBUG(0, ("winreg_get_printer_dataex: Could not query value %s: %s\n",
2411 value, nt_errstr(status)));
2412 result = ntstatus_to_werror(status);
2415 if (!W_ERROR_IS_OK(result)) {
2420 *data_size = data_in_size;
2422 *data = talloc_move(mem_ctx, &data_in);
2427 if (winreg_handle != NULL) {
2430 if (is_valid_policy_hnd(&key_hnd)) {
2431 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
2433 if (is_valid_policy_hnd(&hive_hnd)) {
2434 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
2438 TALLOC_FREE(tmp_ctx);
2442 /* Enumerate on the values of a given key and provide the data. */
2443 WERROR winreg_enum_printer_dataex(TALLOC_CTX *mem_ctx,
2444 const struct auth_serversupplied_info *session_info,
2445 struct messaging_context *msg_ctx,
2446 const char *printer,
2448 uint32_t *pnum_values,
2449 struct spoolss_PrinterEnumValues **penum_values)
2451 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2452 struct dcerpc_binding_handle *winreg_handle = NULL;
2453 struct policy_handle hive_hnd, key_hnd;
2455 struct spoolss_PrinterEnumValues *enum_values = NULL;
2456 uint32_t num_values = 0;
2458 WERROR result = WERR_OK;
2460 TALLOC_CTX *tmp_ctx;
2462 tmp_ctx = talloc_stackframe();
2463 if (tmp_ctx == NULL) {
2467 path = winreg_printer_data_keyname(tmp_ctx, printer);
2469 TALLOC_FREE(tmp_ctx);
2473 result = winreg_printer_openkey(tmp_ctx,
2483 if (!W_ERROR_IS_OK(result)) {
2484 DEBUG(2, ("winreg_enum_printer_dataex: Could not open key %s: %s\n",
2485 key, win_errstr(result)));
2489 result = winreg_printer_enumvalues(tmp_ctx,
2494 if (!W_ERROR_IS_OK(result)) {
2495 DEBUG(0, ("winreg_enum_printer_dataex: Could not enumerate values in %s: %s\n",
2496 key, win_errstr(result)));
2500 *pnum_values = num_values;
2502 *penum_values = talloc_move(mem_ctx, &enum_values);
2507 if (winreg_handle != NULL) {
2510 if (is_valid_policy_hnd(&key_hnd)) {
2511 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
2513 if (is_valid_policy_hnd(&hive_hnd)) {
2514 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
2518 TALLOC_FREE(tmp_ctx);
2522 /* Delete printer data over a winreg pipe. */
2523 WERROR winreg_delete_printer_dataex(TALLOC_CTX *mem_ctx,
2524 const struct auth_serversupplied_info *session_info,
2525 struct messaging_context *msg_ctx,
2526 const char *printer,
2530 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2531 struct dcerpc_binding_handle *winreg_handle = NULL;
2532 struct policy_handle hive_hnd, key_hnd;
2533 struct winreg_String wvalue = { 0, };
2535 WERROR result = WERR_OK;
2538 TALLOC_CTX *tmp_ctx;
2540 tmp_ctx = talloc_stackframe();
2541 if (tmp_ctx == NULL) {
2545 path = winreg_printer_data_keyname(tmp_ctx, printer);
2547 TALLOC_FREE(tmp_ctx);
2551 ZERO_STRUCT(hive_hnd);
2552 ZERO_STRUCT(key_hnd);
2554 result = winreg_printer_openkey(tmp_ctx,
2564 if (!W_ERROR_IS_OK(result)) {
2565 DEBUG(0, ("winreg_delete_printer_dataex: Could not open key %s: %s\n",
2566 key, win_errstr(result)));
2570 wvalue.name = value;
2571 status = dcerpc_winreg_DeleteValue(winreg_handle,
2576 if (!NT_STATUS_IS_OK(status)) {
2577 DEBUG(0, ("winreg_delete_printer_dataex: Could not delete value %s: %s\n",
2578 value, nt_errstr(status)));
2579 result = ntstatus_to_werror(status);
2583 if (winreg_handle != NULL) {
2586 if (is_valid_policy_hnd(&key_hnd)) {
2587 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
2589 if (is_valid_policy_hnd(&hive_hnd)) {
2590 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
2594 TALLOC_FREE(tmp_ctx);
2598 /* Enumerate on the subkeys of a given key and provide the data. */
2599 WERROR winreg_enum_printer_key(TALLOC_CTX *mem_ctx,
2600 const struct auth_serversupplied_info *session_info,
2601 struct messaging_context *msg_ctx,
2602 const char *printer,
2604 uint32_t *pnum_subkeys,
2605 const char ***psubkeys)
2607 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2608 struct dcerpc_binding_handle *winreg_handle = NULL;
2609 struct policy_handle hive_hnd, key_hnd;
2611 const char **subkeys = NULL;
2612 uint32_t num_subkeys = -1;
2614 WERROR result = WERR_OK;
2617 TALLOC_CTX *tmp_ctx;
2619 tmp_ctx = talloc_stackframe();
2620 if (tmp_ctx == NULL) {
2624 path = winreg_printer_data_keyname(tmp_ctx, printer);
2626 TALLOC_FREE(tmp_ctx);
2630 ZERO_STRUCT(hive_hnd);
2631 ZERO_STRUCT(key_hnd);
2633 result = winreg_printer_openkey(tmp_ctx,
2643 if (!W_ERROR_IS_OK(result)) {
2644 DEBUG(2, ("winreg_enum_printer_key: Could not open key %s: %s\n",
2645 key, win_errstr(result)));
2649 status = dcerpc_winreg_enum_keys(tmp_ctx,
2655 if (!NT_STATUS_IS_OK(status)) {
2656 result = ntstatus_to_werror(status);
2658 if (!W_ERROR_IS_OK(result)) {
2659 DEBUG(0, ("winreg_enum_printer_key: Could not enumerate subkeys in %s: %s\n",
2660 key, win_errstr(result)));
2664 *pnum_subkeys = num_subkeys;
2666 *psubkeys = talloc_move(mem_ctx, &subkeys);
2671 if (winreg_handle != NULL) {
2674 if (is_valid_policy_hnd(&key_hnd)) {
2675 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
2677 if (is_valid_policy_hnd(&hive_hnd)) {
2678 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
2682 TALLOC_FREE(tmp_ctx);
2686 /* Delete a key with subkeys of a given printer. */
2687 WERROR winreg_delete_printer_key(TALLOC_CTX *mem_ctx,
2688 const struct auth_serversupplied_info *session_info,
2689 struct messaging_context *msg_ctx,
2690 const char *printer,
2693 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2694 struct dcerpc_binding_handle *winreg_handle = NULL;
2695 struct policy_handle hive_hnd, key_hnd;
2699 TALLOC_CTX *tmp_ctx;
2701 tmp_ctx = talloc_stackframe();
2702 if (tmp_ctx == NULL) {
2706 path = winreg_printer_data_keyname(tmp_ctx, printer);
2708 TALLOC_FREE(tmp_ctx);
2712 result = winreg_printer_openkey(tmp_ctx,
2722 if (!W_ERROR_IS_OK(result)) {
2723 /* key doesn't exist */
2724 if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
2729 DEBUG(0, ("winreg_delete_printer_key: Could not open key %s: %s\n",
2730 key, win_errstr(result)));
2734 if (is_valid_policy_hnd(&key_hnd)) {
2735 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &result);
2738 if (key == NULL || key[0] == '\0') {
2741 keyname = talloc_asprintf(tmp_ctx,
2745 if (keyname == NULL) {
2746 result = WERR_NOMEM;
2751 result = winreg_printer_delete_subkeys(tmp_ctx,
2756 if (!W_ERROR_IS_OK(result)) {
2757 DEBUG(0, ("winreg_delete_printer_key: Could not delete key %s: %s\n",
2758 key, win_errstr(result)));
2763 if (winreg_handle != NULL) {
2766 if (is_valid_policy_hnd(&key_hnd)) {
2767 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
2769 if (is_valid_policy_hnd(&hive_hnd)) {
2770 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
2774 TALLOC_FREE(tmp_ctx);
2778 WERROR winreg_printer_update_changeid(TALLOC_CTX *mem_ctx,
2779 const struct auth_serversupplied_info *session_info,
2780 struct messaging_context *msg_ctx,
2781 const char *printer)
2783 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2784 struct dcerpc_binding_handle *winreg_handle = NULL;
2785 struct policy_handle hive_hnd, key_hnd;
2789 TALLOC_CTX *tmp_ctx;
2791 tmp_ctx = talloc_stackframe();
2792 if (tmp_ctx == NULL) {
2796 path = winreg_printer_data_keyname(tmp_ctx, printer);
2798 TALLOC_FREE(tmp_ctx);
2802 ZERO_STRUCT(hive_hnd);
2803 ZERO_STRUCT(key_hnd);
2805 result = winreg_printer_openkey(tmp_ctx,
2815 if (!W_ERROR_IS_OK(result)) {
2816 DEBUG(0, ("winreg_printer_update_changeid: Could not open key %s: %s\n",
2817 path, win_errstr(result)));
2821 status = dcerpc_winreg_set_dword(tmp_ctx,
2825 winreg_printer_rev_changeid(),
2827 if (!NT_STATUS_IS_OK(status)) {
2828 result = ntstatus_to_werror(status);
2830 if (!W_ERROR_IS_OK(result)) {
2836 if (winreg_handle != NULL) {
2839 if (is_valid_policy_hnd(&key_hnd)) {
2840 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
2842 if (is_valid_policy_hnd(&hive_hnd)) {
2843 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
2847 TALLOC_FREE(tmp_ctx);
2851 WERROR winreg_printer_get_changeid(TALLOC_CTX *mem_ctx,
2852 const struct auth_serversupplied_info *session_info,
2853 struct messaging_context *msg_ctx,
2854 const char *printer,
2855 uint32_t *pchangeid)
2857 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2858 struct dcerpc_binding_handle *winreg_handle = NULL;
2859 struct policy_handle hive_hnd, key_hnd;
2860 uint32_t changeid = 0;
2864 TALLOC_CTX *tmp_ctx;
2866 tmp_ctx = talloc_stackframe();
2867 if (tmp_ctx == NULL) {
2871 path = winreg_printer_data_keyname(tmp_ctx, printer);
2873 TALLOC_FREE(tmp_ctx);
2877 ZERO_STRUCT(hive_hnd);
2878 ZERO_STRUCT(key_hnd);
2880 result = winreg_printer_openkey(tmp_ctx,
2890 if (!W_ERROR_IS_OK(result)) {
2891 DEBUG(2, ("winreg_printer_get_changeid: Could not open key %s: %s\n",
2892 path, win_errstr(result)));
2896 DEBUG(10, ("winreg_printer_get_changeid: get changeid from %s\n", path));
2898 status = dcerpc_winreg_query_dword(tmp_ctx,
2904 if (!NT_STATUS_IS_OK(status)) {
2905 result = ntstatus_to_werror(status);
2907 if (!W_ERROR_IS_OK(result)) {
2912 *pchangeid = changeid;
2917 if (winreg_handle != NULL) {
2920 if (is_valid_policy_hnd(&key_hnd)) {
2921 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
2923 if (is_valid_policy_hnd(&hive_hnd)) {
2924 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
2928 TALLOC_FREE(tmp_ctx);
2933 * The special behaviour of the spoolss forms is documented at the website:
2935 * Managing Win32 Printserver Forms
2936 * http://unixwiz.net/techtips/winspooler-forms.html
2939 WERROR winreg_printer_addform1(TALLOC_CTX *mem_ctx,
2940 const struct auth_serversupplied_info *session_info,
2941 struct messaging_context *msg_ctx,
2942 struct spoolss_AddFormInfo1 *form)
2944 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2945 struct dcerpc_binding_handle *winreg_handle = NULL;
2946 struct policy_handle hive_hnd, key_hnd;
2947 struct winreg_String wvalue = { 0, };
2949 uint32_t num_info = 0;
2950 union spoolss_FormInfo *info = NULL;
2954 TALLOC_CTX *tmp_ctx;
2956 tmp_ctx = talloc_stackframe();
2957 if (tmp_ctx == NULL) {
2961 ZERO_STRUCT(hive_hnd);
2962 ZERO_STRUCT(key_hnd);
2964 result = winreg_printer_openkey(tmp_ctx,
2968 TOP_LEVEL_CONTROL_FORMS_KEY,
2974 if (!W_ERROR_IS_OK(result)) {
2975 DEBUG(0, ("winreg_printer_addform1: Could not open key %s: %s\n",
2976 TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
2980 result = winreg_printer_enumforms1(tmp_ctx, session_info, msg_ctx,
2982 if (!W_ERROR_IS_OK(result)) {
2983 DEBUG(0, ("winreg_printer_addform: Could not enum keys %s: %s\n",
2984 TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
2988 /* If form name already exists or is builtin return ALREADY_EXISTS */
2989 for (i = 0; i < num_info; i++) {
2990 if (strequal(info[i].info1.form_name, form->form_name)) {
2991 result = WERR_FILE_EXISTS;
2996 wvalue.name = form->form_name;
2998 blob = data_blob_talloc(tmp_ctx, NULL, 32);
2999 SIVAL(blob.data, 0, form->size.width);
3000 SIVAL(blob.data, 4, form->size.height);
3001 SIVAL(blob.data, 8, form->area.left);
3002 SIVAL(blob.data, 12, form->area.top);
3003 SIVAL(blob.data, 16, form->area.right);
3004 SIVAL(blob.data, 20, form->area.bottom);
3005 SIVAL(blob.data, 24, num_info + 1); /* FIXME */
3006 SIVAL(blob.data, 28, form->flags);
3008 status = dcerpc_winreg_SetValue(winreg_handle,
3016 if (!NT_STATUS_IS_OK(status)) {
3017 DEBUG(0, ("winreg_printer_addform1: Could not set value %s: %s\n",
3018 wvalue.name, nt_errstr(status)));
3019 result = ntstatus_to_werror(status);
3023 if (winreg_handle != NULL) {
3026 if (is_valid_policy_hnd(&key_hnd)) {
3027 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
3029 if (is_valid_policy_hnd(&hive_hnd)) {
3030 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
3035 TALLOC_FREE(tmp_ctx);
3039 WERROR winreg_printer_enumforms1(TALLOC_CTX *mem_ctx,
3040 const struct auth_serversupplied_info *session_info,
3041 struct messaging_context *msg_ctx,
3042 uint32_t *pnum_info,
3043 union spoolss_FormInfo **pinfo)
3045 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3046 struct dcerpc_binding_handle *winreg_handle = NULL;
3047 struct policy_handle hive_hnd, key_hnd;
3048 union spoolss_FormInfo *info;
3049 struct spoolss_PrinterEnumValues *enum_values = NULL;
3050 uint32_t num_values = 0;
3051 uint32_t num_builtin = ARRAY_SIZE(builtin_forms1);
3054 TALLOC_CTX *tmp_ctx;
3056 tmp_ctx = talloc_stackframe();
3057 if (tmp_ctx == NULL) {
3061 ZERO_STRUCT(hive_hnd);
3062 ZERO_STRUCT(key_hnd);
3064 result = winreg_printer_openkey(tmp_ctx,
3068 TOP_LEVEL_CONTROL_FORMS_KEY,
3074 if (!W_ERROR_IS_OK(result)) {
3075 /* key doesn't exist */
3076 if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
3081 DEBUG(0, ("winreg_printer_enumforms1: Could not open key %s: %s\n",
3082 TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
3086 result = winreg_printer_enumvalues(tmp_ctx,
3091 if (!W_ERROR_IS_OK(result)) {
3092 DEBUG(0, ("winreg_printer_enumforms1: Could not enumerate values in %s: %s\n",
3093 TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
3097 info = talloc_array(tmp_ctx, union spoolss_FormInfo, num_builtin + num_values);
3099 result = WERR_NOMEM;
3103 /* Enumerate BUILTIN forms */
3104 for (i = 0; i < num_builtin; i++) {
3105 info[i].info1 = builtin_forms1[i];
3108 /* Enumerate registry forms */
3109 for (i = 0; i < num_values; i++) {
3110 union spoolss_FormInfo val;
3112 if (enum_values[i].type != REG_BINARY ||
3113 enum_values[i].data_length != 32) {
3117 val.info1.form_name = talloc_strdup(info, enum_values[i].value_name);
3118 if (val.info1.form_name == NULL) {
3119 result = WERR_NOMEM;
3123 val.info1.size.width = IVAL(enum_values[i].data->data, 0);
3124 val.info1.size.height = IVAL(enum_values[i].data->data, 4);
3125 val.info1.area.left = IVAL(enum_values[i].data->data, 8);
3126 val.info1.area.top = IVAL(enum_values[i].data->data, 12);
3127 val.info1.area.right = IVAL(enum_values[i].data->data, 16);
3128 val.info1.area.bottom = IVAL(enum_values[i].data->data, 20);
3129 /* skip form index IVAL(enum_values[i].data->data, 24)));*/
3130 val.info1.flags = (enum spoolss_FormFlags) IVAL(enum_values[i].data->data, 28);
3132 info[i + num_builtin] = val;
3135 *pnum_info = num_builtin + num_values;
3137 *pinfo = talloc_move(mem_ctx, &info);
3141 if (winreg_handle != NULL) {
3144 if (is_valid_policy_hnd(&key_hnd)) {
3145 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
3147 if (is_valid_policy_hnd(&hive_hnd)) {
3148 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
3152 TALLOC_FREE(enum_values);
3153 TALLOC_FREE(tmp_ctx);
3157 WERROR winreg_printer_deleteform1(TALLOC_CTX *mem_ctx,
3158 const struct auth_serversupplied_info *session_info,
3159 struct messaging_context *msg_ctx,
3160 const char *form_name)
3162 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3163 struct dcerpc_binding_handle *winreg_handle = NULL;
3164 struct policy_handle hive_hnd, key_hnd;
3165 struct winreg_String wvalue = { 0, };
3166 uint32_t num_builtin = ARRAY_SIZE(builtin_forms1);
3168 WERROR result = WERR_OK;
3170 TALLOC_CTX *tmp_ctx;
3172 for (i = 0; i < num_builtin; i++) {
3173 if (strequal(builtin_forms1[i].form_name, form_name)) {
3174 return WERR_INVALID_PARAMETER;
3178 tmp_ctx = talloc_stackframe();
3179 if (tmp_ctx == NULL) {
3183 ZERO_STRUCT(hive_hnd);
3184 ZERO_STRUCT(key_hnd);
3186 result = winreg_printer_openkey(tmp_ctx,
3190 TOP_LEVEL_CONTROL_FORMS_KEY,
3196 if (!W_ERROR_IS_OK(result)) {
3197 DEBUG(0, ("winreg_printer_deleteform1: Could not open key %s: %s\n",
3198 TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
3199 if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
3200 result = WERR_INVALID_FORM_NAME;
3205 wvalue.name = form_name;
3206 status = dcerpc_winreg_DeleteValue(winreg_handle,
3211 if (!NT_STATUS_IS_OK(status)) {
3212 /* If the value doesn't exist, return WERR_INVALID_FORM_NAME */
3213 DEBUG(0, ("winreg_printer_delteform1: Could not delete value %s: %s\n",
3214 wvalue.name, nt_errstr(status)));
3215 result = ntstatus_to_werror(status);
3219 if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
3220 result = WERR_INVALID_FORM_NAME;
3224 if (winreg_handle != NULL) {
3227 if (is_valid_policy_hnd(&key_hnd)) {
3228 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
3230 if (is_valid_policy_hnd(&hive_hnd)) {
3231 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
3235 TALLOC_FREE(tmp_ctx);
3239 WERROR winreg_printer_setform1(TALLOC_CTX *mem_ctx,
3240 const struct auth_serversupplied_info *session_info,
3241 struct messaging_context *msg_ctx,
3242 const char *form_name,
3243 struct spoolss_AddFormInfo1 *form)
3245 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3246 struct dcerpc_binding_handle *winreg_handle = NULL;
3247 struct policy_handle hive_hnd, key_hnd;
3248 struct winreg_String wvalue = { 0, };
3250 uint32_t num_builtin = ARRAY_SIZE(builtin_forms1);
3254 TALLOC_CTX *tmp_ctx = NULL;
3256 for (i = 0; i < num_builtin; i++) {
3257 if (strequal(builtin_forms1[i].form_name, form->form_name)) {
3258 result = WERR_INVALID_PARAM;
3263 tmp_ctx = talloc_stackframe();
3264 if (tmp_ctx == NULL) {
3268 ZERO_STRUCT(hive_hnd);
3269 ZERO_STRUCT(key_hnd);
3271 result = winreg_printer_openkey(tmp_ctx,
3275 TOP_LEVEL_CONTROL_FORMS_KEY,
3281 if (!W_ERROR_IS_OK(result)) {
3282 DEBUG(0, ("winreg_printer_setform1: Could not open key %s: %s\n",
3283 TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
3287 /* If form_name != form->form_name then we renamed the form */
3288 if (strequal(form_name, form->form_name)) {
3289 result = winreg_printer_deleteform1(tmp_ctx, session_info,
3290 msg_ctx, form_name);
3291 if (!W_ERROR_IS_OK(result)) {
3292 DEBUG(0, ("winreg_printer_setform1: Could not open key %s: %s\n",
3293 TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
3298 wvalue.name = form->form_name;
3300 blob = data_blob_talloc(tmp_ctx, NULL, 32);
3301 SIVAL(blob.data, 0, form->size.width);
3302 SIVAL(blob.data, 4, form->size.height);
3303 SIVAL(blob.data, 8, form->area.left);
3304 SIVAL(blob.data, 12, form->area.top);
3305 SIVAL(blob.data, 16, form->area.right);
3306 SIVAL(blob.data, 20, form->area.bottom);
3307 SIVAL(blob.data, 24, 42);
3308 SIVAL(blob.data, 28, form->flags);
3310 status = dcerpc_winreg_SetValue(winreg_handle,
3318 if (!NT_STATUS_IS_OK(status)) {
3319 DEBUG(0, ("winreg_printer_setform1: Could not set value %s: %s\n",
3320 wvalue.name, nt_errstr(status)));
3321 result = ntstatus_to_werror(status);
3325 if (winreg_handle != NULL) {
3328 if (is_valid_policy_hnd(&key_hnd)) {
3329 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
3331 if (is_valid_policy_hnd(&hive_hnd)) {
3332 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
3336 TALLOC_FREE(tmp_ctx);
3340 WERROR winreg_printer_getform1(TALLOC_CTX *mem_ctx,
3341 const struct auth_serversupplied_info *session_info,
3342 struct messaging_context *msg_ctx,
3343 const char *form_name,
3344 struct spoolss_FormInfo1 *r)
3346 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3347 struct dcerpc_binding_handle *winreg_handle = NULL;
3348 struct policy_handle hive_hnd, key_hnd;
3349 struct winreg_String wvalue;
3350 enum winreg_Type type_in = REG_NONE;
3351 uint8_t *data_in = NULL;
3352 uint32_t data_in_size = 0;
3353 uint32_t value_len = 0;
3354 uint32_t num_builtin = ARRAY_SIZE(builtin_forms1);
3358 TALLOC_CTX *tmp_ctx;
3360 /* check builtin forms first */
3361 for (i = 0; i < num_builtin; i++) {
3362 if (strequal(builtin_forms1[i].form_name, form_name)) {
3363 *r = builtin_forms1[i];
3368 tmp_ctx = talloc_stackframe();
3369 if (tmp_ctx == NULL) {
3373 ZERO_STRUCT(hive_hnd);
3374 ZERO_STRUCT(key_hnd);
3376 result = winreg_printer_openkey(tmp_ctx,
3380 TOP_LEVEL_CONTROL_FORMS_KEY,
3386 if (!W_ERROR_IS_OK(result)) {
3387 DEBUG(2, ("winreg_printer_getform1: Could not open key %s: %s\n",
3388 TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
3392 wvalue.name = form_name;
3395 * call QueryValue once with data == NULL to get the
3396 * needed memory size to be allocated, then allocate
3397 * data buffer and call again.
3399 status = dcerpc_winreg_QueryValue(winreg_handle,
3408 if (!NT_STATUS_IS_OK(status)) {
3409 DEBUG(0, ("winreg_printer_getform1: Could not query value %s: %s\n",
3410 wvalue.name, nt_errstr(status)));
3411 result = ntstatus_to_werror(status);
3414 if (!W_ERROR_IS_OK(result)) {
3418 data_in = (uint8_t *) TALLOC(tmp_ctx, data_in_size);
3419 if (data_in == NULL) {
3420 result = WERR_NOMEM;
3425 status = dcerpc_winreg_QueryValue(winreg_handle,
3434 if (!NT_STATUS_IS_OK(status)) {
3435 DEBUG(0, ("winreg_printer_getform1: Could not query value %s: %s\n",
3436 wvalue.name, nt_errstr(status)));
3437 result = ntstatus_to_werror(status);
3440 if (!W_ERROR_IS_OK(result)) {
3444 r->form_name = talloc_strdup(mem_ctx, form_name);
3445 if (r->form_name == NULL) {
3446 result = WERR_NOMEM;
3450 r->size.width = IVAL(data_in, 0);
3451 r->size.height = IVAL(data_in, 4);
3452 r->area.left = IVAL(data_in, 8);
3453 r->area.top = IVAL(data_in, 12);
3454 r->area.right = IVAL(data_in, 16);
3455 r->area.bottom = IVAL(data_in, 20);
3456 /* skip index IVAL(data_in, 24)));*/
3457 r->flags = (enum spoolss_FormFlags) IVAL(data_in, 28);
3461 if (winreg_handle != NULL) {
3464 if (is_valid_policy_hnd(&key_hnd)) {
3465 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
3467 if (is_valid_policy_hnd(&hive_hnd)) {
3468 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
3472 TALLOC_FREE(tmp_ctx);
3476 WERROR winreg_add_driver(TALLOC_CTX *mem_ctx,
3477 const struct auth_serversupplied_info *session_info,
3478 struct messaging_context *msg_ctx,
3479 struct spoolss_AddDriverInfoCtr *r,
3480 const char **driver_name,
3481 uint32_t *driver_version)
3483 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3484 struct dcerpc_binding_handle *winreg_handle = NULL;
3485 struct policy_handle hive_hnd, key_hnd;
3486 struct spoolss_DriverInfo8 info8;
3487 TALLOC_CTX *tmp_ctx = NULL;
3491 ZERO_STRUCT(hive_hnd);
3492 ZERO_STRUCT(key_hnd);
3495 if (!driver_info_ctr_to_info8(r, &info8)) {
3496 result = WERR_INVALID_PARAMETER;
3500 tmp_ctx = talloc_stackframe();
3501 if (tmp_ctx == NULL) {
3505 result = winreg_printer_opendriver(tmp_ctx,
3515 if (!W_ERROR_IS_OK(result)) {
3516 DEBUG(0, ("winreg_add_driver: "
3517 "Could not open driver key (%s,%s,%d): %s\n",
3518 info8.driver_name, info8.architecture,
3519 info8.version, win_errstr(result)));
3523 /* TODO: "Attributes" ? */
3525 status = dcerpc_winreg_set_dword(tmp_ctx,
3531 if (!NT_STATUS_IS_OK(status)) {
3532 result = ntstatus_to_werror(status);
3534 if (!W_ERROR_IS_OK(result)) {
3538 status = dcerpc_winreg_set_sz(tmp_ctx,
3544 if (!NT_STATUS_IS_OK(status)) {
3545 result = ntstatus_to_werror(status);
3547 if (!W_ERROR_IS_OK(result)) {
3551 status = dcerpc_winreg_set_sz(tmp_ctx,
3557 if (!NT_STATUS_IS_OK(status)) {
3558 result = ntstatus_to_werror(status);
3560 if (!W_ERROR_IS_OK(result)) {
3564 status = dcerpc_winreg_set_sz(tmp_ctx,
3567 "Configuration File",
3570 if (!NT_STATUS_IS_OK(status)) {
3571 result = ntstatus_to_werror(status);
3573 if (!W_ERROR_IS_OK(result)) {
3577 status = dcerpc_winreg_set_sz(tmp_ctx,
3583 if (!NT_STATUS_IS_OK(status)) {
3584 result = ntstatus_to_werror(status);
3586 if (!W_ERROR_IS_OK(result)) {
3590 status = dcerpc_winreg_set_multi_sz(tmp_ctx,
3594 info8.dependent_files,
3596 if (!NT_STATUS_IS_OK(status)) {
3597 result = ntstatus_to_werror(status);
3599 if (!W_ERROR_IS_OK(result)) {
3603 status = dcerpc_winreg_set_sz(tmp_ctx,
3609 if (!NT_STATUS_IS_OK(status)) {
3610 result = ntstatus_to_werror(status);
3612 if (!W_ERROR_IS_OK(result)) {
3616 status = dcerpc_winreg_set_sz(tmp_ctx,
3620 info8.default_datatype,
3622 if (!NT_STATUS_IS_OK(status)) {
3623 result = ntstatus_to_werror(status);
3625 if (!W_ERROR_IS_OK(result)) {
3629 status = dcerpc_winreg_set_multi_sz(tmp_ctx,
3631 &key_hnd, "Previous Names",
3632 info8.previous_names,
3634 if (!NT_STATUS_IS_OK(status)) {
3635 result = ntstatus_to_werror(status);
3637 if (!W_ERROR_IS_OK(result)) {
3641 result = winreg_printer_write_date(tmp_ctx, winreg_handle,
3642 &key_hnd, "DriverDate",
3644 if (!W_ERROR_IS_OK(result)) {
3648 result = winreg_printer_write_ver(tmp_ctx, winreg_handle,
3649 &key_hnd, "DriverVersion",
3650 info8.driver_version);
3651 if (!W_ERROR_IS_OK(result)) {
3655 status = dcerpc_winreg_set_sz(tmp_ctx,
3659 info8.manufacturer_name,
3661 if (!NT_STATUS_IS_OK(status)) {
3662 result = ntstatus_to_werror(status);
3664 if (!W_ERROR_IS_OK(result)) {
3668 status = dcerpc_winreg_set_sz(tmp_ctx,
3672 info8.manufacturer_url,
3674 if (!NT_STATUS_IS_OK(status)) {
3675 result = ntstatus_to_werror(status);
3677 if (!W_ERROR_IS_OK(result)) {
3681 status = dcerpc_winreg_set_sz(tmp_ctx,
3687 if (!NT_STATUS_IS_OK(status)) {
3688 result = ntstatus_to_werror(status);
3690 if (!W_ERROR_IS_OK(result)) {
3694 status = dcerpc_winreg_set_sz(tmp_ctx,
3700 if (!NT_STATUS_IS_OK(status)) {
3701 result = ntstatus_to_werror(status);
3703 if (!W_ERROR_IS_OK(result)) {
3707 status = dcerpc_winreg_set_sz(tmp_ctx,
3711 info8.print_processor,
3713 if (!NT_STATUS_IS_OK(status)) {
3714 result = ntstatus_to_werror(status);
3716 if (!W_ERROR_IS_OK(result)) {
3720 status = dcerpc_winreg_set_sz(tmp_ctx,
3726 if (!NT_STATUS_IS_OK(status)) {
3727 result = ntstatus_to_werror(status);
3729 if (!W_ERROR_IS_OK(result)) {
3733 status = dcerpc_winreg_set_multi_sz(tmp_ctx,
3737 info8.color_profiles,
3739 if (!NT_STATUS_IS_OK(status)) {
3740 result = ntstatus_to_werror(status);
3742 if (!W_ERROR_IS_OK(result)) {
3746 status = dcerpc_winreg_set_sz(tmp_ctx,
3752 if (!NT_STATUS_IS_OK(status)) {
3753 result = ntstatus_to_werror(status);
3755 if (!W_ERROR_IS_OK(result)) {
3759 status = dcerpc_winreg_set_dword(tmp_ctx,
3762 "PrinterDriverAttributes",
3763 info8.printer_driver_attributes,
3765 if (!NT_STATUS_IS_OK(status)) {
3766 result = ntstatus_to_werror(status);
3768 if (!W_ERROR_IS_OK(result)) {
3772 status = dcerpc_winreg_set_multi_sz(tmp_ctx,
3776 info8.core_driver_dependencies,
3778 if (!NT_STATUS_IS_OK(status)) {
3779 result = ntstatus_to_werror(status);
3781 if (!W_ERROR_IS_OK(result)) {
3785 result = winreg_printer_write_date(tmp_ctx, winreg_handle,
3786 &key_hnd, "MinInboxDriverVerDate",
3787 info8.min_inbox_driver_ver_date);
3788 if (!W_ERROR_IS_OK(result)) {
3792 result = winreg_printer_write_ver(tmp_ctx, winreg_handle, &key_hnd,
3793 "MinInboxDriverVerVersion",
3794 info8.min_inbox_driver_ver_version);
3795 if (!W_ERROR_IS_OK(result)) {
3799 *driver_name = info8.driver_name;
3800 *driver_version = info8.version;
3803 if (winreg_handle != NULL) {
3806 if (is_valid_policy_hnd(&key_hnd)) {
3807 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
3809 if (is_valid_policy_hnd(&hive_hnd)) {
3810 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
3814 TALLOC_FREE(tmp_ctx);
3818 WERROR winreg_get_driver(TALLOC_CTX *mem_ctx,
3819 const struct auth_serversupplied_info *session_info,
3820 struct messaging_context *msg_ctx,
3821 const char *architecture,
3822 const char *driver_name,
3823 uint32_t driver_version,
3824 struct spoolss_DriverInfo8 **_info8)
3826 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3827 struct dcerpc_binding_handle *winreg_handle = NULL;
3828 struct policy_handle hive_hnd, key_hnd;
3829 struct spoolss_DriverInfo8 i8, *info8;
3830 struct spoolss_PrinterEnumValues *enum_values = NULL;
3831 struct spoolss_PrinterEnumValues *v;
3832 uint32_t num_values = 0;
3833 TALLOC_CTX *tmp_ctx;
3837 ZERO_STRUCT(hive_hnd);
3838 ZERO_STRUCT(key_hnd);
3841 tmp_ctx = talloc_stackframe();
3842 if (tmp_ctx == NULL) {
3846 if (driver_version == DRIVER_ANY_VERSION) {
3847 /* look for Win2k first and then for NT4 */
3848 result = winreg_printer_opendriver(tmp_ctx,
3858 if (!W_ERROR_IS_OK(result)) {
3859 result = winreg_printer_opendriver(tmp_ctx,
3871 /* ok normal case */
3872 result = winreg_printer_opendriver(tmp_ctx,
3883 if (!W_ERROR_IS_OK(result)) {
3884 DEBUG(5, ("winreg_get_driver: "
3885 "Could not open driver key (%s,%s,%d): %s\n",
3886 driver_name, architecture,
3887 driver_version, win_errstr(result)));
3891 result = winreg_printer_enumvalues(tmp_ctx,
3896 if (!W_ERROR_IS_OK(result)) {
3897 DEBUG(0, ("winreg_get_driver: "
3898 "Could not enumerate values for (%s,%s,%d): %s\n",
3899 driver_name, architecture,
3900 driver_version, win_errstr(result)));
3904 info8 = talloc_zero(tmp_ctx, struct spoolss_DriverInfo8);
3905 if (info8 == NULL) {
3906 result = WERR_NOMEM;
3910 info8->driver_name = talloc_strdup(info8, driver_name);
3911 if (info8->driver_name == NULL) {
3912 result = WERR_NOMEM;
3916 info8->architecture = talloc_strdup(info8, architecture);
3917 if (info8->architecture == NULL) {
3918 result = WERR_NOMEM;
3924 for (i = 0; i < num_values; i++) {
3925 const char *tmp_str;
3928 v = &enum_values[i];
3930 result = winreg_enumval_to_dword(info8, v,
3933 if (NT_STATUS_IS_OK(result)) {
3934 info8->version = (enum spoolss_DriverOSVersion) tmp;
3936 CHECK_ERROR(result);
3938 result = winreg_enumval_to_sz(info8, v,
3940 &info8->driver_path);
3941 CHECK_ERROR(result);
3943 result = winreg_enumval_to_sz(info8, v,
3946 CHECK_ERROR(result);
3948 result = winreg_enumval_to_sz(info8, v,
3949 "Configuration File",
3950 &info8->config_file);
3951 CHECK_ERROR(result);
3953 result = winreg_enumval_to_sz(info8, v,
3956 CHECK_ERROR(result);
3958 result = winreg_enumval_to_multi_sz(info8, v,
3960 &info8->dependent_files);
3961 CHECK_ERROR(result);
3963 result = winreg_enumval_to_sz(info8, v,
3965 &info8->monitor_name);
3966 CHECK_ERROR(result);
3968 result = winreg_enumval_to_sz(info8, v,
3970 &info8->default_datatype);
3971 CHECK_ERROR(result);
3973 result = winreg_enumval_to_multi_sz(info8, v,
3975 &info8->previous_names);
3976 CHECK_ERROR(result);
3978 result = winreg_enumval_to_sz(info8, v,
3981 if (W_ERROR_IS_OK(result)) {
3982 result = winreg_printer_date_to_NTTIME(tmp_str,
3983 &info8->driver_date);
3985 CHECK_ERROR(result);
3987 result = winreg_enumval_to_sz(info8, v,
3990 if (W_ERROR_IS_OK(result)) {
3991 result = winreg_printer_ver_to_dword(tmp_str,
3992 &info8->driver_version);
3994 CHECK_ERROR(result);
3996 result = winreg_enumval_to_sz(info8, v,
3998 &info8->manufacturer_name);
3999 CHECK_ERROR(result);
4001 result = winreg_enumval_to_sz(info8, v,
4003 &info8->manufacturer_url);
4004 CHECK_ERROR(result);
4006 result = winreg_enumval_to_sz(info8, v,
4008 &info8->hardware_id);
4009 CHECK_ERROR(result);
4011 result = winreg_enumval_to_sz(info8, v,
4014 CHECK_ERROR(result);
4016 result = winreg_enumval_to_sz(info8, v,
4018 &info8->print_processor);
4019 CHECK_ERROR(result);
4021 result = winreg_enumval_to_sz(info8, v,
4023 &info8->vendor_setup);
4024 CHECK_ERROR(result);
4026 result = winreg_enumval_to_multi_sz(info8, v,
4028 &info8->color_profiles);
4029 CHECK_ERROR(result);
4031 result = winreg_enumval_to_sz(info8, v,
4034 CHECK_ERROR(result);
4036 result = winreg_enumval_to_dword(info8, v,
4037 "PrinterDriverAttributes",
4038 &info8->printer_driver_attributes);
4039 CHECK_ERROR(result);
4041 result = winreg_enumval_to_multi_sz(info8, v,
4043 &info8->core_driver_dependencies);
4044 CHECK_ERROR(result);
4046 result = winreg_enumval_to_sz(info8, v,
4047 "MinInboxDriverVerDate",
4049 if (W_ERROR_IS_OK(result)) {
4050 result = winreg_printer_date_to_NTTIME(tmp_str,
4051 &info8->min_inbox_driver_ver_date);
4053 CHECK_ERROR(result);
4055 result = winreg_enumval_to_sz(info8, v,
4056 "MinInboxDriverVerVersion",
4058 if (W_ERROR_IS_OK(result)) {
4059 result = winreg_printer_ver_to_dword(tmp_str,
4060 &info8->min_inbox_driver_ver_version);
4062 CHECK_ERROR(result);
4065 if (!W_ERROR_IS_OK(result)) {
4066 DEBUG(0, ("winreg_enumval_to_TYPE() failed "
4067 "for %s: %s\n", v->value_name,
4068 win_errstr(result)));
4072 *_info8 = talloc_steal(mem_ctx, info8);
4075 if (winreg_handle != NULL) {
4078 if (is_valid_policy_hnd(&key_hnd)) {
4079 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
4081 if (is_valid_policy_hnd(&hive_hnd)) {
4082 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
4086 TALLOC_FREE(tmp_ctx);
4090 WERROR winreg_del_driver(TALLOC_CTX *mem_ctx,
4091 const struct auth_serversupplied_info *session_info,
4092 struct messaging_context *msg_ctx,
4093 struct spoolss_DriverInfo8 *info8,
4096 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4097 struct dcerpc_binding_handle *winreg_handle = NULL;
4098 struct policy_handle hive_hnd, key_hnd;
4099 TALLOC_CTX *tmp_ctx;
4103 ZERO_STRUCT(hive_hnd);
4104 ZERO_STRUCT(key_hnd);
4106 tmp_ctx = talloc_stackframe();
4107 if (tmp_ctx == NULL) {
4111 /* test that the key exists */
4112 result = winreg_printer_opendriver(tmp_ctx,
4116 info8->architecture,
4122 if (!W_ERROR_IS_OK(result)) {
4123 /* key doesn't exist */
4124 if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
4129 DEBUG(5, ("winreg_del_driver: "
4130 "Could not open driver (%s,%s,%u): %s\n",
4131 info8->driver_name, info8->architecture,
4132 version, win_errstr(result)));
4137 if (is_valid_policy_hnd(&key_hnd)) {
4138 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &result);
4141 key_name = talloc_asprintf(tmp_ctx,
4142 "%s\\Environments\\%s\\Drivers\\Version-%u\\%s",
4143 TOP_LEVEL_CONTROL_KEY,
4144 info8->architecture, version,
4145 info8->driver_name);
4146 if (key_name == NULL) {
4147 result = WERR_NOMEM;
4151 result = winreg_printer_delete_subkeys(tmp_ctx,
4156 if (!W_ERROR_IS_OK(result)) {
4157 DEBUG(0, ("winreg_del_driver: "
4158 "Could not open driver (%s,%s,%u): %s\n",
4159 info8->driver_name, info8->architecture,
4160 version, win_errstr(result)));
4166 if (winreg_handle != NULL) {
4169 if (is_valid_policy_hnd(&key_hnd)) {
4170 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
4172 if (is_valid_policy_hnd(&hive_hnd)) {
4173 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
4177 TALLOC_FREE(tmp_ctx);
4181 WERROR winreg_get_driver_list(TALLOC_CTX *mem_ctx,
4182 const struct auth_serversupplied_info *session_info,
4183 struct messaging_context *msg_ctx,
4184 const char *architecture,
4186 uint32_t *num_drivers,
4187 const char ***drivers_p)
4189 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
4190 struct dcerpc_binding_handle *winreg_handle = NULL;
4191 struct policy_handle hive_hnd, key_hnd;
4192 const char **drivers;
4193 TALLOC_CTX *tmp_ctx;
4200 ZERO_STRUCT(hive_hnd);
4201 ZERO_STRUCT(key_hnd);
4203 tmp_ctx = talloc_stackframe();
4204 if (tmp_ctx == NULL) {
4208 /* use NULL for the driver name so we open the key that is
4209 * parent of all drivers for this architecture and version */
4210 result = winreg_printer_opendriver(tmp_ctx,
4220 if (!W_ERROR_IS_OK(result)) {
4221 DEBUG(5, ("winreg_get_driver_list: "
4222 "Could not open key (%s,%u): %s\n",
4223 architecture, version, win_errstr(result)));
4228 status = dcerpc_winreg_enum_keys(tmp_ctx,
4234 if (!NT_STATUS_IS_OK(status)) {
4235 result = ntstatus_to_werror(status);
4237 if (!W_ERROR_IS_OK(result)) {
4238 DEBUG(0, ("winreg_get_driver_list: "
4239 "Could not enumerate drivers for (%s,%u): %s\n",
4240 architecture, version, win_errstr(result)));
4244 *drivers_p = talloc_steal(mem_ctx, drivers);
4248 if (winreg_handle != NULL) {
4251 if (is_valid_policy_hnd(&key_hnd)) {
4252 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
4254 if (is_valid_policy_hnd(&hive_hnd)) {
4255 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
4259 TALLOC_FREE(tmp_ctx);