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"
34 #define TOP_LEVEL_PRINT_KEY "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print"
35 #define TOP_LEVEL_PRINT_PRINTERS_KEY TOP_LEVEL_PRINT_KEY "\\Printers"
36 #define TOP_LEVEL_CONTROL_KEY "SYSTEM\\CurrentControlSet\\Control\\Print"
37 #define TOP_LEVEL_CONTROL_FORMS_KEY TOP_LEVEL_CONTROL_KEY "\\Forms"
39 #define EMPTY_STRING ""
41 #define FILL_STRING(mem_ctx, in, out) \
43 if (in && strlen(in)) { \
44 out = talloc_strdup(mem_ctx, in); \
46 out = talloc_strdup(mem_ctx, ""); \
48 W_ERROR_HAVE_NO_MEMORY(out); \
51 #define CHECK_ERROR(result) \
52 if (W_ERROR_IS_OK(result)) continue; \
53 if (W_ERROR_EQUAL(result, WERR_NOT_FOUND)) result = WERR_OK; \
54 if (!W_ERROR_IS_OK(result)) break
56 /* FLAGS, NAME, with, height, left, top, right, bottom */
57 static const struct spoolss_FormInfo1 builtin_forms1
[] = {
58 { SPOOLSS_FORM_BUILTIN
, "10x11", {0x3e030,0x44368}, {0x0,0x0,0x3e030,0x44368} },
59 { SPOOLSS_FORM_BUILTIN
, "10x14", {0x3e030,0x56d10}, {0x0,0x0,0x3e030,0x56d10} },
60 { SPOOLSS_FORM_BUILTIN
, "11x17", {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} },
61 { SPOOLSS_FORM_BUILTIN
, "12x11", {0x4a724,0x443e1}, {0x0,0x0,0x4a724,0x443e1} },
62 { SPOOLSS_FORM_BUILTIN
, "15x11", {0x5d048,0x44368}, {0x0,0x0,0x5d048,0x44368} },
63 { SPOOLSS_FORM_BUILTIN
, "6 3/4 Envelope", {0x167ab,0x284ec}, {0x0,0x0,0x167ab,0x284ec} },
64 { SPOOLSS_FORM_BUILTIN
, "9x11", {0x37cf8,0x44368}, {0x0,0x0,0x37cf8,0x44368} },
65 { SPOOLSS_FORM_BUILTIN
, "A0", {0xcd528,0x122488},{0x0,0x0,0xcd528,0x122488} },
66 { SPOOLSS_FORM_BUILTIN
, "A1", {0x91050,0xcd528}, {0x0,0x0,0x91050,0xcd528} },
67 { SPOOLSS_FORM_BUILTIN
, "A2", {0x668a0,0x91050}, {0x0,0x0,0x668a0,0x91050} },
68 { SPOOLSS_FORM_BUILTIN
, "A3 Extra Transverse", {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} },
69 { SPOOLSS_FORM_BUILTIN
, "A3 Extra", {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} },
70 { SPOOLSS_FORM_BUILTIN
, "A3 Rotated", {0x668a0,0x48828}, {0x0,0x0,0x668a0,0x48828} },
71 { SPOOLSS_FORM_BUILTIN
, "A3 Transverse", {0x48828,0x668a0}, {0x0,0x0,0x48828,0x668a0} },
72 { SPOOLSS_FORM_BUILTIN
, "A3", {0x48828,0x668a0}, {0x0,0x0,0x48828,0x668a0} },
73 { SPOOLSS_FORM_BUILTIN
, "A4 Extra", {0x397c2,0x4eb16}, {0x0,0x0,0x397c2,0x4eb16} },
74 { SPOOLSS_FORM_BUILTIN
, "A4 Plus", {0x33450,0x50910}, {0x0,0x0,0x33450,0x50910} },
75 { SPOOLSS_FORM_BUILTIN
, "A4 Rotated", {0x48828,0x33450}, {0x0,0x0,0x48828,0x33450} },
76 { SPOOLSS_FORM_BUILTIN
, "A4 Small", {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
77 { SPOOLSS_FORM_BUILTIN
, "A4 Transverse", {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
78 { SPOOLSS_FORM_BUILTIN
, "A4", {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
79 { SPOOLSS_FORM_BUILTIN
, "A5 Extra", {0x2a7b0,0x395f8}, {0x0,0x0,0x2a7b0,0x395f8} },
80 { SPOOLSS_FORM_BUILTIN
, "A5 Rotated", {0x33450,0x24220}, {0x0,0x0,0x33450,0x24220} },
81 { SPOOLSS_FORM_BUILTIN
, "A5 Transverse", {0x24220,0x33450}, {0x0,0x0,0x24220,0x33450} },
82 { SPOOLSS_FORM_BUILTIN
, "A5", {0x24220,0x33450}, {0x0,0x0,0x24220,0x33450} },
83 { SPOOLSS_FORM_BUILTIN
, "A6 Rotated", {0x24220,0x19a28}, {0x0,0x0,0x24220,0x19a28} },
84 { SPOOLSS_FORM_BUILTIN
, "A6", {0x19a28,0x24220}, {0x0,0x0,0x19a28,0x24220} },
85 { SPOOLSS_FORM_BUILTIN
, "B4 (ISO)", {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} },
86 { SPOOLSS_FORM_BUILTIN
, "B4 (JIS) Rotated", {0x58de0,0x3ebe8}, {0x0,0x0,0x58de0,0x3ebe8} },
87 { SPOOLSS_FORM_BUILTIN
, "B4 (JIS)", {0x3ebe8,0x58de0}, {0x0,0x0,0x3ebe8,0x58de0} },
88 { SPOOLSS_FORM_BUILTIN
, "B5 (ISO) Extra", {0x31128,0x43620}, {0x0,0x0,0x31128,0x43620} },
89 { SPOOLSS_FORM_BUILTIN
, "B5 (JIS) Rotated", {0x3ebe8,0x2c6f0}, {0x0,0x0,0x3ebe8,0x2c6f0} },
90 { SPOOLSS_FORM_BUILTIN
, "B5 (JIS) Transverse", {0x2c6f0,0x3ebe8}, {0x0,0x0,0x2c6f0,0x3ebe8} },
91 { SPOOLSS_FORM_BUILTIN
, "B5 (JIS)", {0x2c6f0,0x3ebe8}, {0x0,0x0,0x2c6f0,0x3ebe8} },
92 { SPOOLSS_FORM_BUILTIN
, "B6 (JIS) Rotated", {0x2c6f0,0x1f400}, {0x0,0x0,0x2c6f0,0x1f400} },
93 { SPOOLSS_FORM_BUILTIN
, "B6 (JIS)", {0x1f400,0x2c6f0}, {0x0,0x0,0x1f400,0x2c6f0} },
94 { SPOOLSS_FORM_BUILTIN
, "C size sheet", {0x696b8,0x886d0}, {0x0,0x0,0x696b8,0x886d0} },
95 { SPOOLSS_FORM_BUILTIN
, "D size sheet", {0x886d0,0xd2d70}, {0x0,0x0,0x886d0,0xd2d70} },
96 { SPOOLSS_FORM_BUILTIN
, "Double Japan Postcard Rotated", {0x24220,0x30d40}, {0x0,0x0,0x24220,0x30d40} },
97 { SPOOLSS_FORM_BUILTIN
, "E size sheet", {0xd2d70,0x110da0},{0x0,0x0,0xd2d70,0x110da0} },
98 { SPOOLSS_FORM_BUILTIN
, "Envelope #10", {0x19947,0x3ae94}, {0x0,0x0,0x19947,0x3ae94} },
99 { SPOOLSS_FORM_BUILTIN
, "Envelope #11", {0x1be7c,0x40565}, {0x0,0x0,0x1be7c,0x40565} },
100 { SPOOLSS_FORM_BUILTIN
, "Envelope #12", {0x1d74a,0x44368}, {0x0,0x0,0x1d74a,0x44368} },
101 { SPOOLSS_FORM_BUILTIN
, "Envelope #14", {0x1f018,0x47504}, {0x0,0x0,0x1f018,0x47504} },
102 { SPOOLSS_FORM_BUILTIN
, "Envelope #9", {0x18079,0x37091}, {0x0,0x0,0x18079,0x37091} },
103 { SPOOLSS_FORM_BUILTIN
, "Envelope B4", {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} },
104 { SPOOLSS_FORM_BUILTIN
, "Envelope B5", {0x2af80,0x3d090}, {0x0,0x0,0x2af80,0x3d090} },
105 { SPOOLSS_FORM_BUILTIN
, "Envelope B6", {0x2af80,0x1e848}, {0x0,0x0,0x2af80,0x1e848} },
106 { SPOOLSS_FORM_BUILTIN
, "Envelope C3", {0x4f1a0,0x6fd10}, {0x0,0x0,0x4f1a0,0x6fd10} },
107 { SPOOLSS_FORM_BUILTIN
, "Envelope C4", {0x37e88,0x4f1a0}, {0x0,0x0,0x37e88,0x4f1a0} },
108 { SPOOLSS_FORM_BUILTIN
, "Envelope C5", {0x278d0,0x37e88}, {0x0,0x0,0x278d0,0x37e88} },
109 { SPOOLSS_FORM_BUILTIN
, "Envelope C6", {0x1bd50,0x278d0}, {0x0,0x0,0x1bd50,0x278d0} },
110 { SPOOLSS_FORM_BUILTIN
, "Envelope C65", {0x1bd50,0x37e88}, {0x0,0x0,0x1bd50,0x37e88} },
111 { SPOOLSS_FORM_BUILTIN
, "Envelope DL", {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} },
112 { SPOOLSS_FORM_BUILTIN
, "Envelope Invite", {0x35b60,0x35b60}, {0x0,0x0,0x35b60,0x35b60} },
113 { SPOOLSS_FORM_BUILTIN
, "Envelope Monarch", {0x18079,0x2e824}, {0x0,0x0,0x18079,0x2e824} },
114 { SPOOLSS_FORM_BUILTIN
, "Envelope", {0x1adb0,0x38270}, {0x0,0x0,0x1adb0,0x38270} },
115 { SPOOLSS_FORM_BUILTIN
, "Executive", {0x2cf56,0x411cc}, {0x0,0x0,0x2cf56,0x411cc} },
116 { SPOOLSS_FORM_BUILTIN
, "Folio", {0x34b5c,0x509d8}, {0x0,0x0,0x34b5c,0x509d8} },
117 { SPOOLSS_FORM_BUILTIN
, "German Legal Fanfold", {0x34b5c,0x509d8}, {0x0,0x0,0x34b5c,0x509d8} },
118 { SPOOLSS_FORM_BUILTIN
, "German Std Fanfold", {0x34b5c,0x4a6a0}, {0x0,0x0,0x34b5c,0x4a6a0} },
119 { SPOOLSS_FORM_BUILTIN
, "Japan Envelope Chou #3 Rotated", {0x395f8,0x1d4c0}, {0x0,0x0,0x395f8,0x1d4c0} },
120 { SPOOLSS_FORM_BUILTIN
, "Japan Envelope Chou #4 Rotated", {0x320c8,0x15f90}, {0x0,0x0,0x320c8,0x15f90} },
121 { SPOOLSS_FORM_BUILTIN
, "Japan Envelope Kaku #2 Rotated", {0x510e0,0x3a980}, {0x0,0x0,0x510e0,0x3a980} },
122 { SPOOLSS_FORM_BUILTIN
, "Japan Envelope Kaku #3 Rotated", {0x43a08,0x34bc0}, {0x0,0x0,0x43a08,0x34bc0} },
123 { SPOOLSS_FORM_BUILTIN
, "Japan Envelope You #4 Rotated", {0x395f8,0x19a28}, {0x0,0x0,0x395f8,0x19a28} },
124 { SPOOLSS_FORM_BUILTIN
, "Japan Envelope You #4", {0x19a28,0x395f8}, {0x0,0x0,0x19a28,0x395f8} },
125 { SPOOLSS_FORM_BUILTIN
, "Japanese Double Postcard", {0x30d40,0x24220}, {0x0,0x0,0x30d40,0x24220} },
126 { SPOOLSS_FORM_BUILTIN
, "Japanese Envelope Chou #3", {0x1d4c0,0x395f8}, {0x0,0x0,0x1d4c0,0x395f8} },
127 { SPOOLSS_FORM_BUILTIN
, "Japanese Envelope Chou #4", {0x15f90,0x320c8}, {0x0,0x0,0x15f90,0x320c8} },
128 { SPOOLSS_FORM_BUILTIN
, "Japanese Envelope Kaku #2", {0x3a980,0x510e0}, {0x0,0x0,0x3a980,0x510e0} },
129 { SPOOLSS_FORM_BUILTIN
, "Japanese Envelope Kaku #3", {0x34bc0,0x43a08}, {0x0,0x0,0x34bc0,0x43a08} },
130 { SPOOLSS_FORM_BUILTIN
, "Japanese Postcard Rotated", {0x24220,0x186a0}, {0x0,0x0,0x24220,0x186a0} },
131 { SPOOLSS_FORM_BUILTIN
, "Japanese Postcard", {0x186a0,0x24220}, {0x0,0x0,0x186a0,0x24220} },
132 { SPOOLSS_FORM_BUILTIN
, "Ledger", {0x696b8,0x44368}, {0x0,0x0,0x696b8,0x44368} },
133 { SPOOLSS_FORM_BUILTIN
, "Legal Extra", {0x3ae94,0x5d048}, {0x0,0x0,0x3ae94,0x5d048} },
134 { SPOOLSS_FORM_BUILTIN
, "Legal", {0x34b5c,0x56d10}, {0x0,0x0,0x34b5c,0x56d10} },
135 { SPOOLSS_FORM_BUILTIN
, "Letter Extra Transverse", {0x3ae94,0x4a6a0}, {0x0,0x0,0x3ae94,0x4a6a0} },
136 { SPOOLSS_FORM_BUILTIN
, "Letter Extra", {0x3ae94,0x4a6a0}, {0x0,0x0,0x3ae94,0x4a6a0} },
137 { SPOOLSS_FORM_BUILTIN
, "Letter Plus", {0x34b5c,0x4eb16}, {0x0,0x0,0x34b5c,0x4eb16} },
138 { SPOOLSS_FORM_BUILTIN
, "Letter Rotated", {0x44368,0x34b5c}, {0x0,0x0,0x44368,0x34b5c} },
139 { SPOOLSS_FORM_BUILTIN
, "Letter Small", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
140 { SPOOLSS_FORM_BUILTIN
, "Letter Transverse", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
141 { SPOOLSS_FORM_BUILTIN
, "Letter", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
142 { SPOOLSS_FORM_BUILTIN
, "Note", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
143 { SPOOLSS_FORM_BUILTIN
, "PRC 16K Rotated", {0x3f7a0,0x2de60}, {0x0,0x0,0x3f7a0,0x2de60} },
144 { SPOOLSS_FORM_BUILTIN
, "PRC 16K", {0x2de60,0x3f7a0}, {0x0,0x0,0x2de60,0x3f7a0} },
145 { SPOOLSS_FORM_BUILTIN
, "PRC 32K Rotated", {0x2cec0,0x1fbd0}, {0x0,0x0,0x2cec0,0x1fbd0} },
146 { SPOOLSS_FORM_BUILTIN
, "PRC 32K", {0x1fbd0,0x2cec0}, {0x0,0x0,0x1fbd0,0x2cec0} },
147 { SPOOLSS_FORM_BUILTIN
, "PRC 32K(Big) Rotated", {0x318f8,0x222e0}, {0x0,0x0,0x318f8,0x222e0} },
148 { SPOOLSS_FORM_BUILTIN
, "PRC 32K(Big)", {0x222e0,0x318f8}, {0x0,0x0,0x222e0,0x318f8} },
149 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #1 Rotated", {0x28488,0x18e70}, {0x0,0x0,0x28488,0x18e70} },
150 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #1", {0x18e70,0x28488}, {0x0,0x0,0x18e70,0x28488} },
151 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #10 Rotated", {0x6fd10,0x4f1a0}, {0x0,0x0,0x6fd10,0x4f1a0} },
152 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #10", {0x4f1a0,0x6fd10}, {0x0,0x0,0x4f1a0,0x6fd10} },
153 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #2 Rotated", {0x2af80,0x18e70}, {0x0,0x0,0x2af80,0x18e70} },
154 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #2", {0x18e70,0x2af80}, {0x0,0x0,0x18e70,0x2af80} },
155 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #3 Rotated", {0x2af80,0x1e848}, {0x0,0x0,0x2af80,0x1e848} },
156 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #3", {0x1e848,0x2af80}, {0x0,0x0,0x1e848,0x2af80} },
157 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #4 Rotated", {0x32c80,0x1adb0}, {0x0,0x0,0x32c80,0x1adb0} },
158 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #4", {0x1adb0,0x32c80}, {0x0,0x0,0x1adb0,0x32c80} },
159 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #5 Rotated", {0x35b60,0x1adb0}, {0x0,0x0,0x35b60,0x1adb0} },
160 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #5", {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} },
161 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #6 Rotated", {0x38270,0x1d4c0}, {0x0,0x0,0x38270,0x1d4c0} },
162 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #6", {0x1d4c0,0x38270}, {0x0,0x0,0x1d4c0,0x38270} },
163 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #7 Rotated", {0x38270,0x27100}, {0x0,0x0,0x38270,0x27100} },
164 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #7", {0x27100,0x38270}, {0x0,0x0,0x27100,0x38270} },
165 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #8 Rotated", {0x4b708,0x1d4c0}, {0x0,0x0,0x4b708,0x1d4c0} },
166 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #8", {0x1d4c0,0x4b708}, {0x0,0x0,0x1d4c0,0x4b708} },
167 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #9 Rotated", {0x4f1a0,0x37e88}, {0x0,0x0,0x4f1a0,0x37e88} },
168 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #9", {0x37e88,0x4f1a0}, {0x0,0x0,0x37e88,0x4f1a0} },
169 { SPOOLSS_FORM_BUILTIN
, "Quarto", {0x347d8,0x43238}, {0x0,0x0,0x347d8,0x43238} },
170 { SPOOLSS_FORM_BUILTIN
, "Reserved48", {0x1,0x1}, {0x0,0x0,0x1,0x1} },
171 { SPOOLSS_FORM_BUILTIN
, "Reserved49", {0x1,0x1}, {0x0,0x0,0x1,0x1} },
172 { SPOOLSS_FORM_BUILTIN
, "Statement", {0x221b4,0x34b5c}, {0x0,0x0,0x221b4,0x34b5c} },
173 { SPOOLSS_FORM_BUILTIN
, "Super A", {0x376b8,0x56ea0}, {0x0,0x0,0x376b8,0x56ea0} },
174 { SPOOLSS_FORM_BUILTIN
, "Super B", {0x4a768,0x76e58}, {0x0,0x0,0x4a768,0x76e58} },
175 { SPOOLSS_FORM_BUILTIN
, "Tabloid Extra", {0x4a6a0,0x6f9f0}, {0x0,0x0,0x4a6a0,0x6f9f0} },
176 { SPOOLSS_FORM_BUILTIN
, "Tabloid", {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} },
177 { SPOOLSS_FORM_BUILTIN
, "US Std Fanfold", {0x5c3e1,0x44368}, {0x0,0x0,0x5c3e1,0x44368} }
180 /********************************************************************
181 static helper functions
182 ********************************************************************/
184 /****************************************************************************
185 Update the changeid time.
186 ****************************************************************************/
190 * @brief Update the ChangeID time of a printer.
192 * This is SO NASTY as some drivers need this to change, others need it
193 * static. This value will change every second, and I must hope that this
194 * is enough..... DON'T CHANGE THIS CODE WITHOUT A TEST MATRIX THE SIZE OF
197 * @return The ChangeID.
199 static uint32_t winreg_printer_rev_changeid(void)
203 get_process_uptime(&tv
);
206 /* Return changeid as msec since spooler restart */
207 return tv
.tv_sec
* 1000 + tv
.tv_usec
/ 1000;
210 * This setting seems to work well but is too untested
211 * to replace the above calculation. Left in for experimentation
212 * of the reader --jerry (Tue Mar 12 09:15:05 CST 2002)
214 return tv
.tv_sec
* 10 + tv
.tv_usec
/ 100000;
221 * @brief Connect to the interal winreg server and open the given printer key.
223 * The function will create the needed subkeys if they don't exist.
225 * @param[in] mem_ctx The memory context to use.
227 * @param[in] session_info The supplied server info.
229 * @param[out] binding_handle A pointer for the winreg dcerpc binding handle.
231 * @param[in] path The path to the key to open.
233 * @param[in] key The key to open.
235 * @param[in] create_key Set to true if the key should be created if it
238 * @param[in] access_mask The access mask to open the key.
240 * @param[out] hive_handle A policy handle for the opened hive.
242 * @param[out] key_handle A policy handle for the opened key.
244 * @return WERR_OK on success, the corresponding DOS error
245 * code if something gone wrong.
247 static WERROR
winreg_printer_openkey(TALLOC_CTX
*mem_ctx
,
248 const struct auth_serversupplied_info
*session_info
,
249 struct messaging_context
*msg_ctx
,
250 struct dcerpc_binding_handle
**winreg_binding_handle
,
254 uint32_t access_mask
,
255 struct policy_handle
*hive_handle
,
256 struct policy_handle
*key_handle
)
258 static struct client_address client_id
;
259 struct dcerpc_binding_handle
*binding_handle
;
260 struct winreg_String wkey
, wkeyclass
;
263 WERROR result
= WERR_OK
;
265 strlcpy(client_id
.addr
, "127.0.0.1", sizeof(client_id
.addr
));
266 client_id
.name
= "127.0.0.1";
268 status
= rpcint_binding_handle(mem_ctx
,
274 if (!NT_STATUS_IS_OK(status
)) {
275 DEBUG(0, ("winreg_printer_openkey: Could not connect to winreg pipe: %s\n",
277 return ntstatus_to_werror(status
);
280 status
= dcerpc_winreg_OpenHKLM(binding_handle
,
286 if (!NT_STATUS_IS_OK(status
)) {
287 DEBUG(0, ("winreg_printer_openkey: Could not open HKLM hive: %s\n",
289 talloc_free(binding_handle
);
290 return ntstatus_to_werror(status
);
292 if (!W_ERROR_IS_OK(result
)) {
293 DEBUG(0, ("winreg_printer_openkey: Could not open HKLM hive: %s\n",
294 win_errstr(result
)));
295 talloc_free(binding_handle
);
300 keyname
= talloc_asprintf(mem_ctx
, "%s\\%s", path
, key
);
302 keyname
= talloc_strdup(mem_ctx
, path
);
304 if (keyname
== NULL
) {
305 talloc_free(binding_handle
);
313 enum winreg_CreateAction action
= REG_ACTION_NONE
;
315 ZERO_STRUCT(wkeyclass
);
318 status
= dcerpc_winreg_CreateKey(binding_handle
,
330 case REG_ACTION_NONE
:
331 DEBUG(8, ("winreg_printer_openkey:createkey did nothing -- huh?\n"));
333 case REG_CREATED_NEW_KEY
:
334 DEBUG(8, ("winreg_printer_openkey: createkey created %s\n", keyname
));
336 case REG_OPENED_EXISTING_KEY
:
337 DEBUG(8, ("winreg_printer_openkey: createkey opened existing %s\n", keyname
));
341 status
= dcerpc_winreg_OpenKey(binding_handle
,
350 if (!NT_STATUS_IS_OK(status
)) {
351 talloc_free(binding_handle
);
352 return ntstatus_to_werror(status
);
354 if (!W_ERROR_IS_OK(result
)) {
355 talloc_free(binding_handle
);
359 *winreg_binding_handle
= binding_handle
;
365 * @brief Create the registry keyname for the given printer.
367 * @param[in] mem_ctx The memory context to use.
369 * @param[in] printer The name of the printer to get the registry key.
371 * @return The registry key or NULL on error.
373 static char *winreg_printer_data_keyname(TALLOC_CTX
*mem_ctx
, const char *printer
) {
374 return talloc_asprintf(mem_ctx
, "%s\\%s", TOP_LEVEL_PRINT_PRINTERS_KEY
, printer
);
380 * @brief Enumerate values of an opened key handle and retrieve the data.
382 * @param[in] mem_ctx The memory context to use.
384 * @param[in] winreg_handle The binding handle for the rpc connection.
386 * @param[in] key_hnd The opened key handle.
388 * @param[out] pnum_values A pointer to store he number of values found.
390 * @param[out] pnum_values A pointer to store the number of values we found.
392 * @return WERR_OK on success, the corresponding DOS error
393 * code if something gone wrong.
395 static WERROR
winreg_printer_enumvalues(TALLOC_CTX
*mem_ctx
,
396 struct dcerpc_binding_handle
*winreg_handle
,
397 struct policy_handle
*key_hnd
,
398 uint32_t *pnum_values
,
399 struct spoolss_PrinterEnumValues
**penum_values
)
402 uint32_t num_subkeys
, max_subkeylen
, max_classlen
;
403 uint32_t num_values
, max_valnamelen
, max_valbufsize
;
404 uint32_t secdescsize
;
406 NTTIME last_changed_time
;
407 struct winreg_String classname
;
409 struct spoolss_PrinterEnumValues
*enum_values
;
411 WERROR result
= WERR_OK
;
414 tmp_ctx
= talloc_stackframe();
415 if (tmp_ctx
== NULL
) {
419 ZERO_STRUCT(classname
);
421 status
= dcerpc_winreg_QueryInfoKey(winreg_handle
,
434 if (!NT_STATUS_IS_OK(status
)) {
435 DEBUG(0, ("winreg_printer_enumvalues: Could not query info: %s\n",
437 result
= ntstatus_to_werror(status
);
440 if (!W_ERROR_IS_OK(result
)) {
441 DEBUG(0, ("winreg_printer_enumvalues: Could not query info: %s\n",
442 win_errstr(result
)));
446 if (num_values
== 0) {
448 TALLOC_FREE(tmp_ctx
);
452 enum_values
= TALLOC_ARRAY(tmp_ctx
, struct spoolss_PrinterEnumValues
, num_values
);
453 if (enum_values
== NULL
) {
458 for (i
= 0; i
< num_values
; i
++) {
459 struct spoolss_PrinterEnumValues val
;
460 struct winreg_ValNameBuf name_buf
;
461 enum winreg_Type type
= REG_NONE
;
468 name_buf
.size
= max_valnamelen
+ 2;
471 data_size
= max_valbufsize
;
474 data
= (uint8_t *) talloc_zero_size(tmp_ctx
, data_size
);
478 status
= dcerpc_winreg_EnumValue(winreg_handle
,
485 data_size
? &data_size
: NULL
,
488 if (W_ERROR_EQUAL(result
, WERR_NO_MORE_ITEMS
) ) {
490 status
= NT_STATUS_OK
;
494 if (!NT_STATUS_IS_OK(status
)) {
495 DEBUG(0, ("winreg_printer_enumvalues: Could not enumerate values: %s\n",
497 result
= ntstatus_to_werror(status
);
500 if (!W_ERROR_IS_OK(result
)) {
501 DEBUG(0, ("winreg_printer_enumvalues: Could not enumerate values: %s\n",
502 win_errstr(result
)));
506 if (name_buf
.name
== NULL
) {
507 result
= WERR_INVALID_PARAMETER
;
511 val
.value_name
= talloc_strdup(enum_values
, name_buf
.name
);
512 if (val
.value_name
== NULL
) {
516 val
.value_name_len
= strlen_m_term(val
.value_name
) * 2;
519 val
.data_length
= length
;
521 if (val
.data_length
) {
522 val
.data
= talloc(enum_values
, DATA_BLOB
);
523 if (val
.data
== NULL
) {
527 *val
.data
= data_blob_talloc(val
.data
, data
, val
.data_length
);
530 enum_values
[i
] = val
;
533 *pnum_values
= num_values
;
535 *penum_values
= talloc_move(mem_ctx
, &enum_values
);
541 TALLOC_FREE(tmp_ctx
);
548 * @brief A function to delete a key and its subkeys recurively.
550 * @param[in] mem_ctx The memory context to use.
552 * @param[in] winreg_handle The binding handle for the rpc connection.
554 * @param[in] hive_handle A opened hive handle to the key.
556 * @param[in] access_mask The access mask to access the key.
558 * @param[in] key The key to delete
560 * @return WERR_OK on success, the corresponding DOS error
561 * code if something gone wrong.
563 static WERROR
winreg_printer_delete_subkeys(TALLOC_CTX
*mem_ctx
,
564 struct dcerpc_binding_handle
*winreg_handle
,
565 struct policy_handle
*hive_handle
,
566 uint32_t access_mask
,
569 const char **subkeys
= NULL
;
570 uint32_t num_subkeys
= 0;
571 struct policy_handle key_hnd
;
572 struct winreg_String wkey
= { 0, };
573 WERROR result
= WERR_OK
;
577 ZERO_STRUCT(key_hnd
);
580 DEBUG(2, ("winreg_printer_delete_subkeys: delete key %s\n", key
));
582 status
= dcerpc_winreg_OpenKey(winreg_handle
,
590 if (!NT_STATUS_IS_OK(status
)) {
591 DEBUG(0, ("winreg_printer_delete_subkeys: Could not open key %s: %s\n",
592 wkey
.name
, nt_errstr(status
)));
593 return ntstatus_to_werror(status
);
595 if (!W_ERROR_IS_OK(result
)) {
596 DEBUG(0, ("winreg_printer_delete_subkeys: Could not open key %s: %s\n",
597 wkey
.name
, win_errstr(result
)));
601 status
= dcerpc_winreg_enum_keys(mem_ctx
,
607 if (!NT_STATUS_IS_OK(status
)) {
608 result
= ntstatus_to_werror(status
);
610 if (!W_ERROR_IS_OK(result
)) {
614 for (i
= 0; i
< num_subkeys
; i
++) {
615 /* create key + subkey */
616 char *subkey
= talloc_asprintf(mem_ctx
, "%s\\%s", key
, subkeys
[i
]);
617 if (subkey
== NULL
) {
621 DEBUG(2, ("winreg_printer_delete_subkeys: delete subkey %s\n", subkey
));
622 result
= winreg_printer_delete_subkeys(mem_ctx
,
627 if (!W_ERROR_IS_OK(result
)) {
632 if (is_valid_policy_hnd(&key_hnd
)) {
634 dcerpc_winreg_CloseKey(winreg_handle
, mem_ctx
, &key_hnd
, &ignore
);
639 status
= dcerpc_winreg_DeleteKey(winreg_handle
,
644 if (!NT_STATUS_IS_OK(status
)) {
645 result
= ntstatus_to_werror(status
);
649 if (is_valid_policy_hnd(&key_hnd
)) {
652 dcerpc_winreg_CloseKey(winreg_handle
, mem_ctx
, &key_hnd
, &ignore
);
658 static WERROR
winreg_printer_opendriver(TALLOC_CTX
*mem_ctx
,
659 const struct auth_serversupplied_info
*session_info
,
660 struct messaging_context
*msg_ctx
,
661 const char *drivername
,
662 const char *architecture
,
664 uint32_t access_mask
,
666 struct dcerpc_binding_handle
**winreg_binding_handle
,
667 struct policy_handle
*hive_hnd
,
668 struct policy_handle
*key_hnd
)
673 key_name
= talloc_asprintf(mem_ctx
, "%s\\Environments\\%s\\Drivers\\Version-%u",
674 TOP_LEVEL_CONTROL_KEY
,
675 architecture
, version
);
680 result
= winreg_printer_openkey(mem_ctx
,
683 winreg_binding_handle
,
693 static WERROR
winreg_enumval_to_dword(TALLOC_CTX
*mem_ctx
,
694 struct spoolss_PrinterEnumValues
*v
,
695 const char *valuename
, uint32_t *dw
)
697 /* just return if it is not the one we are looking for */
698 if (strcmp(valuename
, v
->value_name
) != 0) {
699 return WERR_NOT_FOUND
;
702 if (v
->type
!= REG_DWORD
) {
703 return WERR_INVALID_DATATYPE
;
706 if (v
->data_length
!= 4) {
711 *dw
= IVAL(v
->data
->data
, 0);
715 static WERROR
winreg_enumval_to_sz(TALLOC_CTX
*mem_ctx
,
716 struct spoolss_PrinterEnumValues
*v
,
717 const char *valuename
, const char **_str
)
719 /* just return if it is not the one we are looking for */
720 if (strcmp(valuename
, v
->value_name
) != 0) {
721 return WERR_NOT_FOUND
;
724 if (v
->type
!= REG_SZ
) {
725 return WERR_INVALID_DATATYPE
;
728 if (v
->data_length
== 0) {
729 *_str
= talloc_strdup(mem_ctx
, EMPTY_STRING
);
736 if (!pull_reg_sz(mem_ctx
, v
->data
, _str
)) {
743 static WERROR
winreg_enumval_to_multi_sz(TALLOC_CTX
*mem_ctx
,
744 struct spoolss_PrinterEnumValues
*v
,
745 const char *valuename
,
748 /* just return if it is not the one we are looking for */
749 if (strcmp(valuename
, v
->value_name
) != 0) {
750 return WERR_NOT_FOUND
;
753 if (v
->type
!= REG_MULTI_SZ
) {
754 return WERR_INVALID_DATATYPE
;
757 if (v
->data_length
== 0) {
758 *array
= talloc_array(mem_ctx
, const char *, 1);
759 if (*array
== NULL
) {
766 if (!pull_reg_multi_sz(mem_ctx
, v
->data
, array
)) {
773 static WERROR
winreg_printer_write_date(TALLOC_CTX
*mem_ctx
,
774 struct dcerpc_binding_handle
*winreg_handle
,
775 struct policy_handle
*key_handle
,
779 struct winreg_String wvalue
= { 0, };
781 WERROR result
= WERR_OK
;
788 str
= talloc_strdup(mem_ctx
, "01/01/1601");
790 t
= nt_time_to_unix(data
);
793 return map_werror_from_unix(errno
);
795 str
= talloc_asprintf(mem_ctx
, "%02d/%02d/%04d",
796 tm
->tm_mon
+ 1, tm
->tm_mday
, tm
->tm_year
+ 1900);
803 if (!push_reg_sz(mem_ctx
, &blob
, str
)) {
806 status
= dcerpc_winreg_SetValue(winreg_handle
,
814 if (!NT_STATUS_IS_OK(status
)) {
815 result
= ntstatus_to_werror(status
);
817 if (!W_ERROR_IS_OK(result
)) {
818 DEBUG(0, ("winreg_printer_write_date: Could not set value %s: %s\n",
819 wvalue
.name
, win_errstr(result
)));
825 static WERROR
winreg_printer_date_to_NTTIME(const char *str
, NTTIME
*data
)
830 if (strequal(str
, "01/01/1601")) {
837 if (sscanf(str
, "%d/%d/%d",
838 &tm
.tm_mon
, &tm
.tm_mday
, &tm
.tm_year
) != 3) {
839 return WERR_INVALID_PARAMETER
;
846 unix_to_nt_time(data
, t
);
851 static WERROR
winreg_printer_write_ver(TALLOC_CTX
*mem_ctx
,
852 struct dcerpc_binding_handle
*winreg_handle
,
853 struct policy_handle
*key_handle
,
857 struct winreg_String wvalue
= { 0, };
859 WERROR result
= WERR_OK
;
863 /* FIXME: check format is right,
864 * this needs to be something like: 6.1.7600.16385 */
865 str
= talloc_asprintf(mem_ctx
, "%u.%u.%u.%u",
866 (unsigned)((data
>> 48) & 0xFFFF),
867 (unsigned)((data
>> 32) & 0xFFFF),
868 (unsigned)((data
>> 16) & 0xFFFF),
869 (unsigned)(data
& 0xFFFF));
875 if (!push_reg_sz(mem_ctx
, &blob
, str
)) {
878 status
= dcerpc_winreg_SetValue(winreg_handle
,
886 if (!NT_STATUS_IS_OK(status
)) {
887 result
= ntstatus_to_werror(status
);
889 if (!W_ERROR_IS_OK(result
)) {
890 DEBUG(0, ("winreg_printer_write_date: Could not set value %s: %s\n",
891 wvalue
.name
, win_errstr(result
)));
897 static WERROR
winreg_printer_ver_to_dword(const char *str
, uint64_t *data
)
899 unsigned int v1
, v2
, v3
, v4
;
901 if (sscanf(str
, "%u.%u.%u.%u", &v1
, &v2
, &v3
, &v4
) != 4) {
902 return WERR_INVALID_PARAMETER
;
905 *data
= ((uint64_t)(v1
& 0xFFFF) << 48) +
906 ((uint64_t)(v2
& 0xFFFF) << 32) +
907 ((uint64_t)(v3
& 0xFFFF) << 16) +
908 (uint64_t)(v2
& 0xFFFF);
913 /********************************************************************
914 Public winreg function for spoolss
915 ********************************************************************/
917 WERROR
winreg_create_printer(TALLOC_CTX
*mem_ctx
,
918 const struct auth_serversupplied_info
*session_info
,
919 struct messaging_context
*msg_ctx
,
920 const char *sharename
)
922 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
923 struct dcerpc_binding_handle
*winreg_handle
= NULL
;
924 struct policy_handle hive_hnd
, key_hnd
;
925 struct spoolss_SetPrinterInfo2
*info2
;
926 struct security_descriptor
*secdesc
;
927 struct winreg_String wkey
, wkeyclass
;
929 const char *subkeys
[] = { SPOOL_DSDRIVER_KEY
, SPOOL_DSSPOOLER_KEY
, SPOOL_PRINTERDATA_KEY
};
930 uint32_t i
, count
= ARRAY_SIZE(subkeys
);
931 uint32_t info2_mask
= 0;
932 WERROR result
= WERR_OK
;
935 tmp_ctx
= talloc_stackframe();
936 if (tmp_ctx
== NULL
) {
940 path
= winreg_printer_data_keyname(tmp_ctx
, sharename
);
942 TALLOC_FREE(tmp_ctx
);
946 ZERO_STRUCT(hive_hnd
);
947 ZERO_STRUCT(key_hnd
);
949 result
= winreg_printer_openkey(tmp_ctx
,
959 if (W_ERROR_IS_OK(result
)) {
960 DEBUG(2, ("winreg_create_printer: Skipping, %s already exists\n", path
));
962 } else if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
963 DEBUG(2, ("winreg_create_printer: Creating default values in %s\n", path
));
964 } else if (!W_ERROR_IS_OK(result
)) {
965 DEBUG(0, ("winreg_create_printer: Could not open key %s: %s\n",
966 path
, win_errstr(result
)));
970 /* Create the main key */
971 result
= winreg_printer_openkey(tmp_ctx
,
981 if (!W_ERROR_IS_OK(result
)) {
982 DEBUG(0, ("winreg_create_printer_keys: Could not create key %s: %s\n",
983 path
, win_errstr(result
)));
987 if (is_valid_policy_hnd(&key_hnd
)) {
988 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &result
);
992 for (i
= 0; i
< count
; i
++) {
994 enum winreg_CreateAction action
= REG_ACTION_NONE
;
996 ZERO_STRUCT(key_hnd
);
999 wkey
.name
= talloc_asprintf(tmp_ctx
, "%s\\%s", path
, subkeys
[i
]);
1000 if (wkey
.name
== NULL
) {
1001 result
= WERR_NOMEM
;
1005 ZERO_STRUCT(wkeyclass
);
1006 wkeyclass
.name
= "";
1008 status
= dcerpc_winreg_CreateKey(winreg_handle
,
1019 if (!NT_STATUS_IS_OK(status
)) {
1020 result
= ntstatus_to_werror(status
);
1022 if (!W_ERROR_IS_OK(result
)) {
1023 DEBUG(0, ("winreg_create_printer_keys: Could not create key %s: %s\n",
1024 wkey
.name
, win_errstr(result
)));
1028 if (strequal(subkeys
[i
], SPOOL_DSSPOOLER_KEY
)) {
1029 const char *dnssuffix
;
1030 const char *longname
;
1031 const char *uncname
;
1033 status
= dcerpc_winreg_set_sz(tmp_ctx
,
1036 SPOOL_REG_PRINTERNAME
,
1039 if (!NT_STATUS_IS_OK(status
)) {
1040 result
= ntstatus_to_werror(status
);
1042 if (!W_ERROR_IS_OK(result
)) {
1046 status
= dcerpc_winreg_set_sz(tmp_ctx
,
1049 SPOOL_REG_SHORTSERVERNAME
,
1052 if (!NT_STATUS_IS_OK(status
)) {
1053 result
= ntstatus_to_werror(status
);
1055 if (!W_ERROR_IS_OK(result
)) {
1059 /* We make the assumption that the netbios name
1060 * is the same as the DNS name since the former
1061 * will be what we used to join the domain
1063 dnssuffix
= get_mydnsdomname(tmp_ctx
);
1064 if (dnssuffix
!= NULL
&& dnssuffix
[0] != '\0') {
1065 longname
= talloc_asprintf(tmp_ctx
, "%s.%s", global_myname(), dnssuffix
);
1067 longname
= talloc_strdup(tmp_ctx
, global_myname());
1069 if (longname
== NULL
) {
1070 result
= WERR_NOMEM
;
1074 status
= dcerpc_winreg_set_sz(tmp_ctx
,
1077 SPOOL_REG_SERVERNAME
,
1080 if (!NT_STATUS_IS_OK(status
)) {
1081 result
= ntstatus_to_werror(status
);
1083 if (!W_ERROR_IS_OK(result
)) {
1087 uncname
= talloc_asprintf(tmp_ctx
, "\\\\%s\\%s",
1088 longname
, sharename
);
1089 if (uncname
== NULL
) {
1090 result
= WERR_NOMEM
;
1094 status
= dcerpc_winreg_set_sz(tmp_ctx
,
1100 if (!NT_STATUS_IS_OK(status
)) {
1101 result
= ntstatus_to_werror(status
);
1103 if (!W_ERROR_IS_OK(result
)) {
1107 status
= dcerpc_winreg_set_dword(tmp_ctx
,
1110 SPOOL_REG_VERSIONNUMBER
,
1113 if (!NT_STATUS_IS_OK(status
)) {
1114 result
= ntstatus_to_werror(status
);
1116 if (!W_ERROR_IS_OK(result
)) {
1120 status
= dcerpc_winreg_set_dword(tmp_ctx
,
1123 SPOOL_REG_PRINTSTARTTIME
,
1126 if (!NT_STATUS_IS_OK(status
)) {
1127 result
= ntstatus_to_werror(status
);
1129 if (!W_ERROR_IS_OK(result
)) {
1133 status
= dcerpc_winreg_set_dword(tmp_ctx
,
1136 SPOOL_REG_PRINTENDTIME
,
1139 if (!NT_STATUS_IS_OK(status
)) {
1140 result
= ntstatus_to_werror(status
);
1142 if (!W_ERROR_IS_OK(result
)) {
1146 status
= dcerpc_winreg_set_dword(tmp_ctx
,
1152 if (!NT_STATUS_IS_OK(status
)) {
1153 result
= ntstatus_to_werror(status
);
1155 if (!W_ERROR_IS_OK(result
)) {
1159 status
= dcerpc_winreg_set_dword(tmp_ctx
,
1162 SPOOL_REG_PRINTKEEPPRINTEDJOBS
,
1165 if (!NT_STATUS_IS_OK(status
)) {
1166 result
= ntstatus_to_werror(status
);
1168 if (!W_ERROR_IS_OK(result
)) {
1173 if (is_valid_policy_hnd(&key_hnd
)) {
1174 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &result
);
1177 info2
= talloc_zero(tmp_ctx
, struct spoolss_SetPrinterInfo2
);
1178 if (info2
== NULL
) {
1179 result
= WERR_NOMEM
;
1183 info2
->printername
= sharename
;
1184 if (info2
->printername
== NULL
) {
1185 result
= WERR_NOMEM
;
1188 info2_mask
|= SPOOLSS_PRINTER_INFO_PRINTERNAME
;
1190 info2
->sharename
= sharename
;
1191 info2_mask
|= SPOOLSS_PRINTER_INFO_SHARENAME
;
1193 info2
->portname
= SAMBA_PRINTER_PORT_NAME
;
1194 info2_mask
|= SPOOLSS_PRINTER_INFO_PORTNAME
;
1196 info2
->printprocessor
= "winprint";
1197 info2_mask
|= SPOOLSS_PRINTER_INFO_PRINTPROCESSOR
;
1199 info2
->datatype
= "RAW";
1200 info2_mask
|= SPOOLSS_PRINTER_INFO_DATATYPE
;
1202 info2
->comment
= "";
1203 info2_mask
|= SPOOLSS_PRINTER_INFO_COMMENT
;
1205 info2
->attributes
= PRINTER_ATTRIBUTE_SAMBA
;
1206 info2_mask
|= SPOOLSS_PRINTER_INFO_ATTRIBUTES
;
1208 info2
->starttime
= 0; /* Minutes since 12:00am GMT */
1209 info2_mask
|= SPOOLSS_PRINTER_INFO_STARTTIME
;
1211 info2
->untiltime
= 0; /* Minutes since 12:00am GMT */
1212 info2_mask
|= SPOOLSS_PRINTER_INFO_UNTILTIME
;
1214 info2
->priority
= 1;
1215 info2_mask
|= SPOOLSS_PRINTER_INFO_PRIORITY
;
1217 info2
->defaultpriority
= 1;
1218 info2_mask
|= SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY
;
1220 result
= spoolss_create_default_secdesc(tmp_ctx
, &secdesc
);
1221 if (!W_ERROR_IS_OK(result
)) {
1224 info2_mask
|= SPOOLSS_PRINTER_INFO_SECDESC
;
1227 * Don't write a default Device Mode to the registry! The Device Mode is
1228 * only written to disk with a SetPrinter level 2 or 8.
1231 result
= winreg_update_printer(tmp_ctx
,
1241 if (winreg_handle
!= NULL
) {
1244 if (is_valid_policy_hnd(&key_hnd
)) {
1245 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
1247 if (is_valid_policy_hnd(&hive_hnd
)) {
1248 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
1252 talloc_free(tmp_ctx
);
1256 WERROR
winreg_update_printer(TALLOC_CTX
*mem_ctx
,
1257 const struct auth_serversupplied_info
*session_info
,
1258 struct messaging_context
*msg_ctx
,
1259 const char *sharename
,
1260 uint32_t info2_mask
,
1261 struct spoolss_SetPrinterInfo2
*info2
,
1262 struct spoolss_DeviceMode
*devmode
,
1263 struct security_descriptor
*secdesc
)
1265 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1266 struct dcerpc_binding_handle
*winreg_handle
= NULL
;
1267 struct policy_handle hive_hnd
, key_hnd
;
1268 int snum
= lp_servicenumber(sharename
);
1269 enum ndr_err_code ndr_err
;
1272 WERROR result
= WERR_OK
;
1274 TALLOC_CTX
*tmp_ctx
;
1276 tmp_ctx
= talloc_stackframe();
1277 if (tmp_ctx
== NULL
) {
1281 path
= winreg_printer_data_keyname(tmp_ctx
, sharename
);
1283 TALLOC_FREE(tmp_ctx
);
1287 ZERO_STRUCT(hive_hnd
);
1288 ZERO_STRUCT(key_hnd
);
1290 result
= winreg_printer_openkey(tmp_ctx
,
1300 if (!W_ERROR_IS_OK(result
)) {
1301 DEBUG(0, ("winreg_update_printer: Could not open key %s: %s\n",
1302 path
, win_errstr(result
)));
1306 if (info2_mask
& SPOOLSS_PRINTER_INFO_ATTRIBUTES
) {
1307 status
= dcerpc_winreg_set_dword(tmp_ctx
,
1313 if (!NT_STATUS_IS_OK(status
)) {
1314 result
= ntstatus_to_werror(status
);
1316 if (!W_ERROR_IS_OK(result
)) {
1322 if (info2_mask
& SPOOLSS_PRINTER_INFO_AVERAGEPPM
) {
1323 status
= dcerpc_winreg_set_dword(tmp_ctx
,
1329 if (!NT_STATUS_IS_OK(status
)) {
1330 result
= ntstatus_to_werror(status
);
1332 if (!W_ERROR_IS_OK(result
)) {
1338 if (info2_mask
& SPOOLSS_PRINTER_INFO_COMMENT
) {
1339 status
= dcerpc_winreg_set_sz(tmp_ctx
,
1345 if (!NT_STATUS_IS_OK(status
)) {
1346 result
= ntstatus_to_werror(status
);
1348 if (!W_ERROR_IS_OK(result
)) {
1353 if (info2_mask
& SPOOLSS_PRINTER_INFO_DATATYPE
) {
1354 status
= dcerpc_winreg_set_sz(tmp_ctx
,
1360 if (!NT_STATUS_IS_OK(status
)) {
1361 result
= ntstatus_to_werror(status
);
1363 if (!W_ERROR_IS_OK(result
)) {
1368 if (info2_mask
& SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY
) {
1369 status
= dcerpc_winreg_set_dword(tmp_ctx
,
1373 info2
->defaultpriority
,
1375 if (!NT_STATUS_IS_OK(status
)) {
1376 result
= ntstatus_to_werror(status
);
1378 if (!W_ERROR_IS_OK(result
)) {
1383 if (info2_mask
& SPOOLSS_PRINTER_INFO_DEVMODE
) {
1385 * Some client drivers freak out if there is a NULL devmode
1386 * (probably the driver is not checking before accessing
1387 * the devmode pointer) --jerry
1389 if (devmode
== NULL
&& lp_default_devmode(snum
) && info2
!= NULL
) {
1390 result
= spoolss_create_default_devmode(tmp_ctx
,
1393 if (!W_ERROR_IS_OK(result
)) {
1398 if (devmode
->size
!= (ndr_size_spoolss_DeviceMode(devmode
, 0) - devmode
->__driverextra_length
)) {
1399 result
= WERR_INVALID_PARAM
;
1403 ndr_err
= ndr_push_struct_blob(&blob
, tmp_ctx
, devmode
,
1404 (ndr_push_flags_fn_t
) ndr_push_spoolss_DeviceMode
);
1405 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1406 DEBUG(0, ("winreg_update_printer: Failed to marshall device mode\n"));
1407 result
= WERR_NOMEM
;
1411 status
= dcerpc_winreg_set_binary(tmp_ctx
,
1417 if (!NT_STATUS_IS_OK(status
)) {
1418 result
= ntstatus_to_werror(status
);
1420 if (!W_ERROR_IS_OK(result
)) {
1425 if (info2_mask
& SPOOLSS_PRINTER_INFO_DRIVERNAME
) {
1426 status
= dcerpc_winreg_set_sz(tmp_ctx
,
1432 if (!NT_STATUS_IS_OK(status
)) {
1433 result
= ntstatus_to_werror(status
);
1435 if (!W_ERROR_IS_OK(result
)) {
1440 if (info2_mask
& SPOOLSS_PRINTER_INFO_LOCATION
) {
1441 status
= dcerpc_winreg_set_sz(tmp_ctx
,
1447 if (!NT_STATUS_IS_OK(status
)) {
1448 result
= ntstatus_to_werror(status
);
1450 if (!W_ERROR_IS_OK(result
)) {
1455 if (info2_mask
& SPOOLSS_PRINTER_INFO_PARAMETERS
) {
1456 status
= dcerpc_winreg_set_sz(tmp_ctx
,
1462 if (!NT_STATUS_IS_OK(status
)) {
1463 result
= ntstatus_to_werror(status
);
1465 if (!W_ERROR_IS_OK(result
)) {
1470 if (info2_mask
& SPOOLSS_PRINTER_INFO_PORTNAME
) {
1471 status
= dcerpc_winreg_set_sz(tmp_ctx
,
1477 if (!NT_STATUS_IS_OK(status
)) {
1478 result
= ntstatus_to_werror(status
);
1480 if (!W_ERROR_IS_OK(result
)) {
1485 if (info2_mask
& SPOOLSS_PRINTER_INFO_PRINTERNAME
) {
1487 * in addprinter: no servername and the printer is the name
1488 * in setprinter: servername is \\server
1489 * and printer is \\server\\printer
1491 * Samba manages only local printers.
1492 * we currently don't support things like i
1493 * path=\\other_server\printer
1495 * We only store the printername, not \\server\printername
1497 const char *p
= strrchr(info2
->printername
, '\\');
1499 p
= info2
->printername
;
1503 status
= dcerpc_winreg_set_sz(tmp_ctx
,
1509 if (!NT_STATUS_IS_OK(status
)) {
1510 result
= ntstatus_to_werror(status
);
1512 if (!W_ERROR_IS_OK(result
)) {
1517 if (info2_mask
& SPOOLSS_PRINTER_INFO_PRINTPROCESSOR
) {
1518 status
= dcerpc_winreg_set_sz(tmp_ctx
,
1522 info2
->printprocessor
,
1524 if (!NT_STATUS_IS_OK(status
)) {
1525 result
= ntstatus_to_werror(status
);
1527 if (!W_ERROR_IS_OK(result
)) {
1532 if (info2_mask
& SPOOLSS_PRINTER_INFO_PRIORITY
) {
1533 status
= dcerpc_winreg_set_dword(tmp_ctx
,
1539 if (!NT_STATUS_IS_OK(status
)) {
1540 result
= ntstatus_to_werror(status
);
1542 if (!W_ERROR_IS_OK(result
)) {
1547 if (info2_mask
& SPOOLSS_PRINTER_INFO_SECDESC
) {
1549 * We need a security descriptor, if it isn't specified by
1550 * AddPrinter{Ex} then create a default descriptor.
1552 if (secdesc
== NULL
) {
1553 result
= spoolss_create_default_secdesc(tmp_ctx
, &secdesc
);
1554 if (!W_ERROR_IS_OK(result
)) {
1558 result
= winreg_set_printer_secdesc(tmp_ctx
,
1563 if (!W_ERROR_IS_OK(result
)) {
1568 if (info2_mask
& SPOOLSS_PRINTER_INFO_SEPFILE
) {
1569 status
= dcerpc_winreg_set_sz(tmp_ctx
,
1575 if (!NT_STATUS_IS_OK(status
)) {
1576 result
= ntstatus_to_werror(status
);
1578 if (!W_ERROR_IS_OK(result
)) {
1583 if (info2_mask
& SPOOLSS_PRINTER_INFO_SHARENAME
) {
1584 status
= dcerpc_winreg_set_sz(tmp_ctx
,
1590 if (!NT_STATUS_IS_OK(status
)) {
1591 result
= ntstatus_to_werror(status
);
1593 if (!W_ERROR_IS_OK(result
)) {
1598 if (info2_mask
& SPOOLSS_PRINTER_INFO_STARTTIME
) {
1599 status
= dcerpc_winreg_set_dword(tmp_ctx
,
1605 if (!NT_STATUS_IS_OK(status
)) {
1606 result
= ntstatus_to_werror(status
);
1608 if (!W_ERROR_IS_OK(result
)) {
1613 if (info2_mask
& SPOOLSS_PRINTER_INFO_STATUS
) {
1614 status
= dcerpc_winreg_set_dword(tmp_ctx
,
1620 if (!NT_STATUS_IS_OK(status
)) {
1621 result
= ntstatus_to_werror(status
);
1623 if (!W_ERROR_IS_OK(result
)) {
1628 if (info2_mask
& SPOOLSS_PRINTER_INFO_UNTILTIME
) {
1629 status
= dcerpc_winreg_set_dword(tmp_ctx
,
1635 if (!NT_STATUS_IS_OK(status
)) {
1636 result
= ntstatus_to_werror(status
);
1638 if (!W_ERROR_IS_OK(result
)) {
1643 status
= dcerpc_winreg_set_dword(tmp_ctx
,
1647 winreg_printer_rev_changeid(),
1649 if (!NT_STATUS_IS_OK(status
)) {
1650 result
= ntstatus_to_werror(status
);
1652 if (!W_ERROR_IS_OK(result
)) {
1658 if (winreg_handle
!= NULL
) {
1661 if (is_valid_policy_hnd(&key_hnd
)) {
1662 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
1664 if (is_valid_policy_hnd(&hive_hnd
)) {
1665 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
1669 TALLOC_FREE(tmp_ctx
);
1673 WERROR
winreg_get_printer(TALLOC_CTX
*mem_ctx
,
1674 const struct auth_serversupplied_info
*session_info
,
1675 struct messaging_context
*msg_ctx
,
1676 const char *printer
,
1677 struct spoolss_PrinterInfo2
**pinfo2
)
1679 struct spoolss_PrinterInfo2
*info2
;
1680 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1681 struct dcerpc_binding_handle
*winreg_handle
= NULL
;
1682 struct policy_handle hive_hnd
, key_hnd
;
1683 struct spoolss_PrinterEnumValues
*enum_values
= NULL
;
1684 struct spoolss_PrinterEnumValues
*v
= NULL
;
1685 enum ndr_err_code ndr_err
;
1687 int snum
= lp_servicenumber(printer
);
1688 uint32_t num_values
= 0;
1692 WERROR result
= WERR_OK
;
1693 TALLOC_CTX
*tmp_ctx
;
1695 tmp_ctx
= talloc_stackframe();
1696 if (tmp_ctx
== NULL
) {
1700 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
1702 TALLOC_FREE(tmp_ctx
);
1706 result
= winreg_printer_openkey(tmp_ctx
,
1716 if (!W_ERROR_IS_OK(result
)) {
1717 DEBUG(2, ("winreg_get_printer: Could not open key %s: %s\n",
1718 path
, win_errstr(result
)));
1722 result
= winreg_printer_enumvalues(tmp_ctx
,
1727 if (!W_ERROR_IS_OK(result
)) {
1728 DEBUG(0, ("winreg_get_printer: Could not enumerate values in %s: %s\n",
1729 path
, win_errstr(result
)));
1733 info2
= talloc_zero(tmp_ctx
, struct spoolss_PrinterInfo2
);
1734 if (info2
== NULL
) {
1735 result
= WERR_NOMEM
;
1739 FILL_STRING(info2
, EMPTY_STRING
, info2
->servername
);
1740 FILL_STRING(info2
, EMPTY_STRING
, info2
->printername
);
1741 FILL_STRING(info2
, EMPTY_STRING
, info2
->sharename
);
1742 FILL_STRING(info2
, EMPTY_STRING
, info2
->portname
);
1743 FILL_STRING(info2
, EMPTY_STRING
, info2
->drivername
);
1744 FILL_STRING(info2
, EMPTY_STRING
, info2
->comment
);
1745 FILL_STRING(info2
, EMPTY_STRING
, info2
->location
);
1746 FILL_STRING(info2
, EMPTY_STRING
, info2
->sepfile
);
1747 FILL_STRING(info2
, EMPTY_STRING
, info2
->printprocessor
);
1748 FILL_STRING(info2
, EMPTY_STRING
, info2
->datatype
);
1749 FILL_STRING(info2
, EMPTY_STRING
, info2
->parameters
);
1751 for (i
= 0; i
< num_values
; i
++) {
1752 v
= &enum_values
[i
];
1754 result
= winreg_enumval_to_sz(info2
,
1757 &info2
->printername
);
1758 CHECK_ERROR(result
);
1760 result
= winreg_enumval_to_sz(info2
,
1764 CHECK_ERROR(result
);
1766 result
= winreg_enumval_to_sz(info2
,
1770 CHECK_ERROR(result
);
1772 result
= winreg_enumval_to_sz(info2
,
1776 CHECK_ERROR(result
);
1778 result
= winreg_enumval_to_sz(info2
,
1782 CHECK_ERROR(result
);
1784 result
= winreg_enumval_to_sz(info2
,
1788 CHECK_ERROR(result
);
1790 result
= winreg_enumval_to_sz(info2
,
1793 &info2
->printprocessor
);
1794 CHECK_ERROR(result
);
1796 result
= winreg_enumval_to_sz(info2
,
1800 CHECK_ERROR(result
);
1802 result
= winreg_enumval_to_sz(info2
,
1805 &info2
->parameters
);
1806 CHECK_ERROR(result
);
1808 result
= winreg_enumval_to_sz(info2
,
1811 &info2
->drivername
);
1812 CHECK_ERROR(result
);
1814 result
= winreg_enumval_to_dword(info2
,
1817 &info2
->attributes
);
1818 CHECK_ERROR(result
);
1820 result
= winreg_enumval_to_dword(info2
,
1824 CHECK_ERROR(result
);
1826 result
= winreg_enumval_to_dword(info2
,
1829 &info2
->defaultpriority
);
1830 CHECK_ERROR(result
);
1832 result
= winreg_enumval_to_dword(info2
,
1836 CHECK_ERROR(result
);
1838 result
= winreg_enumval_to_dword(info2
,
1842 CHECK_ERROR(result
);
1844 result
= winreg_enumval_to_dword(info2
,
1848 CHECK_ERROR(result
);
1850 result
= winreg_enumval_to_dword(info2
,
1854 CHECK_ERROR(result
);
1857 if (!W_ERROR_IS_OK(result
)) {
1858 DEBUG(0, ("winreg_get_printer: winreg_enumval_to_TYPE() failed "
1861 win_errstr(result
)));
1865 /* Construct the Device Mode */
1866 status
= dcerpc_winreg_query_binary(tmp_ctx
,
1872 if (!NT_STATUS_IS_OK(status
)) {
1873 result
= ntstatus_to_werror(status
);
1875 if (W_ERROR_IS_OK(result
)) {
1876 info2
->devmode
= talloc_zero(info2
, struct spoolss_DeviceMode
);
1877 if (info2
->devmode
== NULL
) {
1878 result
= WERR_NOMEM
;
1881 ndr_err
= ndr_pull_struct_blob(&blob
,
1884 (ndr_pull_flags_fn_t
) ndr_pull_spoolss_DeviceMode
);
1885 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1886 DEBUG(0, ("winreg_get_printer: Failed to unmarshall device mode\n"));
1887 result
= WERR_NOMEM
;
1892 if (info2
->devmode
== NULL
&& lp_default_devmode(snum
)) {
1893 result
= spoolss_create_default_devmode(info2
,
1896 if (!W_ERROR_IS_OK(result
)) {
1901 if (info2
->devmode
) {
1902 info2
->devmode
->size
= ndr_size_spoolss_DeviceMode(info2
->devmode
, 0) - info2
->devmode
->driverextra_data
.length
;
1905 result
= winreg_get_printer_secdesc(info2
,
1910 if (!W_ERROR_IS_OK(result
)) {
1914 /* Fix for OS/2 drivers. */
1915 if (get_remote_arch() == RA_OS2
) {
1916 spoolss_map_to_os2_driver(info2
, &info2
->drivername
);
1920 *pinfo2
= talloc_move(mem_ctx
, &info2
);
1925 if (winreg_handle
!= NULL
) {
1928 if (is_valid_policy_hnd(&key_hnd
)) {
1929 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
1931 if (is_valid_policy_hnd(&hive_hnd
)) {
1932 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
1936 TALLOC_FREE(tmp_ctx
);
1940 WERROR
winreg_get_printer_secdesc(TALLOC_CTX
*mem_ctx
,
1941 const struct auth_serversupplied_info
*session_info
,
1942 struct messaging_context
*msg_ctx
,
1943 const char *sharename
,
1944 struct spoolss_security_descriptor
**psecdesc
)
1946 struct spoolss_security_descriptor
*secdesc
;
1947 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1948 struct dcerpc_binding_handle
*winreg_handle
= NULL
;
1949 struct policy_handle hive_hnd
, key_hnd
;
1951 TALLOC_CTX
*tmp_ctx
;
1955 tmp_ctx
= talloc_stackframe();
1956 if (tmp_ctx
== NULL
) {
1960 path
= winreg_printer_data_keyname(tmp_ctx
, sharename
);
1962 talloc_free(tmp_ctx
);
1966 ZERO_STRUCT(hive_hnd
);
1967 ZERO_STRUCT(key_hnd
);
1969 result
= winreg_printer_openkey(tmp_ctx
,
1979 if (!W_ERROR_IS_OK(result
)) {
1980 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
1981 goto create_default
;
1986 status
= dcerpc_winreg_query_sd(tmp_ctx
,
1992 if (!NT_STATUS_IS_OK(status
)) {
1993 result
= ntstatus_to_werror(status
);
1995 if (!W_ERROR_IS_OK(result
)) {
1996 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
1997 goto create_default
;
2003 *psecdesc
= talloc_move(mem_ctx
, &secdesc
);
2010 result
= winreg_printer_openkey(tmp_ctx
,
2020 if (!W_ERROR_IS_OK(result
)) {
2024 result
= spoolss_create_default_secdesc(tmp_ctx
, &secdesc
);
2025 if (!W_ERROR_IS_OK(result
)) {
2029 /* If security descriptor is owned by S-1-1-0 and winbindd is up,
2030 this security descriptor has been created when winbindd was
2031 down. Take ownership of security descriptor. */
2032 if (dom_sid_equal(secdesc
->owner_sid
, &global_sid_World
)) {
2033 struct dom_sid owner_sid
;
2035 /* Change sd owner to workgroup administrator */
2037 if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid
)) {
2038 struct spoolss_security_descriptor
*new_secdesc
;
2042 sid_append_rid(&owner_sid
, DOMAIN_RID_ADMINISTRATOR
);
2044 new_secdesc
= make_sec_desc(tmp_ctx
,
2053 if (new_secdesc
== NULL
) {
2054 result
= WERR_NOMEM
;
2058 /* Swap with other one */
2059 secdesc
= new_secdesc
;
2063 status
= dcerpc_winreg_set_sd(tmp_ctx
,
2069 if (!NT_STATUS_IS_OK(status
)) {
2070 result
= ntstatus_to_werror(status
);
2072 if (!W_ERROR_IS_OK(result
)) {
2077 *psecdesc
= talloc_move(mem_ctx
, &secdesc
);
2082 if (winreg_handle
!= NULL
) {
2085 if (is_valid_policy_hnd(&key_hnd
)) {
2086 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
2088 if (is_valid_policy_hnd(&hive_hnd
)) {
2089 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
2093 talloc_free(tmp_ctx
);
2097 WERROR
winreg_set_printer_secdesc(TALLOC_CTX
*mem_ctx
,
2098 const struct auth_serversupplied_info
*session_info
,
2099 struct messaging_context
*msg_ctx
,
2100 const char *sharename
,
2101 const struct spoolss_security_descriptor
*secdesc
)
2103 const struct spoolss_security_descriptor
*new_secdesc
= secdesc
;
2104 struct spoolss_security_descriptor
*old_secdesc
;
2105 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2106 struct dcerpc_binding_handle
*winreg_handle
= NULL
;
2107 struct policy_handle hive_hnd
, key_hnd
;
2109 TALLOC_CTX
*tmp_ctx
;
2113 tmp_ctx
= talloc_stackframe();
2114 if (tmp_ctx
== NULL
) {
2118 path
= winreg_printer_data_keyname(tmp_ctx
, sharename
);
2120 talloc_free(tmp_ctx
);
2125 * The old owner and group sids of the security descriptor are not
2126 * present when new ACEs are added or removed by changing printer
2127 * permissions through NT. If they are NULL in the new security
2128 * descriptor then copy them over from the old one.
2130 if (!secdesc
->owner_sid
|| !secdesc
->group_sid
) {
2131 struct dom_sid
*owner_sid
, *group_sid
;
2132 struct security_acl
*dacl
, *sacl
;
2135 result
= winreg_get_printer_secdesc(tmp_ctx
,
2140 if (!W_ERROR_IS_OK(result
)) {
2141 talloc_free(tmp_ctx
);
2145 /* Pick out correct owner and group sids */
2146 owner_sid
= secdesc
->owner_sid
?
2147 secdesc
->owner_sid
:
2148 old_secdesc
->owner_sid
;
2150 group_sid
= secdesc
->group_sid
?
2151 secdesc
->group_sid
:
2152 old_secdesc
->group_sid
;
2154 dacl
= secdesc
->dacl
?
2158 sacl
= secdesc
->sacl
?
2162 /* Make a deep copy of the security descriptor */
2163 new_secdesc
= make_sec_desc(tmp_ctx
,
2171 if (new_secdesc
== NULL
) {
2172 talloc_free(tmp_ctx
);
2177 ZERO_STRUCT(hive_hnd
);
2178 ZERO_STRUCT(key_hnd
);
2180 result
= winreg_printer_openkey(tmp_ctx
,
2190 if (!W_ERROR_IS_OK(result
)) {
2194 status
= dcerpc_winreg_set_sd(tmp_ctx
,
2200 if (!NT_STATUS_IS_OK(status
)) {
2201 result
= ntstatus_to_werror(status
);
2205 if (winreg_handle
!= NULL
) {
2208 if (is_valid_policy_hnd(&key_hnd
)) {
2209 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
2211 if (is_valid_policy_hnd(&hive_hnd
)) {
2212 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
2216 talloc_free(tmp_ctx
);
2220 /* Set printer data over the winreg pipe. */
2221 WERROR
winreg_set_printer_dataex(TALLOC_CTX
*mem_ctx
,
2222 const struct auth_serversupplied_info
*session_info
,
2223 struct messaging_context
*msg_ctx
,
2224 const char *printer
,
2227 enum winreg_Type type
,
2231 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2232 struct dcerpc_binding_handle
*winreg_handle
= NULL
;
2233 struct policy_handle hive_hnd
, key_hnd
;
2234 struct winreg_String wvalue
= { 0, };
2236 WERROR result
= WERR_OK
;
2238 TALLOC_CTX
*tmp_ctx
;
2240 tmp_ctx
= talloc_stackframe();
2241 if (tmp_ctx
== NULL
) {
2245 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2247 TALLOC_FREE(tmp_ctx
);
2251 ZERO_STRUCT(hive_hnd
);
2252 ZERO_STRUCT(key_hnd
);
2254 DEBUG(8, ("winreg_set_printer_dataex: Open printer key %s, value %s, access_mask: 0x%05x for [%s]\n",
2255 key
, value
, access_mask
, printer
));
2256 result
= winreg_printer_openkey(tmp_ctx
,
2266 if (!W_ERROR_IS_OK(result
)) {
2267 DEBUG(0, ("winreg_set_printer_dataex: Could not open key %s: %s\n",
2268 key
, win_errstr(result
)));
2272 wvalue
.name
= value
;
2273 status
= dcerpc_winreg_SetValue(winreg_handle
,
2281 if (!NT_STATUS_IS_OK(status
)) {
2282 DEBUG(0, ("winreg_set_printer_dataex: Could not set value %s: %s\n",
2283 value
, nt_errstr(status
)));
2284 result
= ntstatus_to_werror(status
);
2288 if (winreg_handle
!= NULL
) {
2291 if (is_valid_policy_hnd(&key_hnd
)) {
2292 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
2294 if (is_valid_policy_hnd(&hive_hnd
)) {
2295 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
2299 TALLOC_FREE(tmp_ctx
);
2303 /* Get printer data over a winreg pipe. */
2304 WERROR
winreg_get_printer_dataex(TALLOC_CTX
*mem_ctx
,
2305 const struct auth_serversupplied_info
*session_info
,
2306 struct messaging_context
*msg_ctx
,
2307 const char *printer
,
2310 enum winreg_Type
*type
,
2312 uint32_t *data_size
)
2314 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2315 struct dcerpc_binding_handle
*winreg_handle
= NULL
;
2316 struct policy_handle hive_hnd
, key_hnd
;
2317 struct winreg_String wvalue
;
2318 enum winreg_Type type_in
= REG_NONE
;
2320 uint8_t *data_in
= NULL
;
2321 uint32_t data_in_size
= 0;
2322 uint32_t value_len
= 0;
2323 WERROR result
= WERR_OK
;
2325 TALLOC_CTX
*tmp_ctx
;
2327 tmp_ctx
= talloc_stackframe();
2328 if (tmp_ctx
== NULL
) {
2332 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2334 TALLOC_FREE(tmp_ctx
);
2338 ZERO_STRUCT(hive_hnd
);
2339 ZERO_STRUCT(key_hnd
);
2341 result
= winreg_printer_openkey(tmp_ctx
,
2351 if (!W_ERROR_IS_OK(result
)) {
2352 DEBUG(2, ("winreg_get_printer_dataex: Could not open key %s: %s\n",
2353 key
, win_errstr(result
)));
2357 wvalue
.name
= value
;
2360 * call QueryValue once with data == NULL to get the
2361 * needed memory size to be allocated, then allocate
2362 * data buffer and call again.
2364 status
= dcerpc_winreg_QueryValue(winreg_handle
,
2373 if (!NT_STATUS_IS_OK(status
)) {
2374 DEBUG(0, ("winreg_get_printer_dataex: Could not query value %s: %s\n",
2375 value
, nt_errstr(status
)));
2376 result
= ntstatus_to_werror(status
);
2379 if (!W_ERROR_IS_OK(result
)) {
2383 data_in
= (uint8_t *) TALLOC(tmp_ctx
, data_in_size
);
2384 if (data_in
== NULL
) {
2385 result
= WERR_NOMEM
;
2390 status
= dcerpc_winreg_QueryValue(winreg_handle
,
2399 if (!NT_STATUS_IS_OK(status
)) {
2400 DEBUG(0, ("winreg_get_printer_dataex: Could not query value %s: %s\n",
2401 value
, nt_errstr(status
)));
2402 result
= ntstatus_to_werror(status
);
2405 if (!W_ERROR_IS_OK(result
)) {
2410 *data_size
= data_in_size
;
2412 *data
= talloc_move(mem_ctx
, &data_in
);
2417 if (winreg_handle
!= NULL
) {
2420 if (is_valid_policy_hnd(&key_hnd
)) {
2421 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
2423 if (is_valid_policy_hnd(&hive_hnd
)) {
2424 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
2428 TALLOC_FREE(tmp_ctx
);
2432 /* Enumerate on the values of a given key and provide the data. */
2433 WERROR
winreg_enum_printer_dataex(TALLOC_CTX
*mem_ctx
,
2434 const struct auth_serversupplied_info
*session_info
,
2435 struct messaging_context
*msg_ctx
,
2436 const char *printer
,
2438 uint32_t *pnum_values
,
2439 struct spoolss_PrinterEnumValues
**penum_values
)
2441 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2442 struct dcerpc_binding_handle
*winreg_handle
= NULL
;
2443 struct policy_handle hive_hnd
, key_hnd
;
2445 struct spoolss_PrinterEnumValues
*enum_values
= NULL
;
2446 uint32_t num_values
= 0;
2448 WERROR result
= WERR_OK
;
2450 TALLOC_CTX
*tmp_ctx
;
2452 tmp_ctx
= talloc_stackframe();
2453 if (tmp_ctx
== NULL
) {
2457 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2459 TALLOC_FREE(tmp_ctx
);
2463 result
= winreg_printer_openkey(tmp_ctx
,
2473 if (!W_ERROR_IS_OK(result
)) {
2474 DEBUG(2, ("winreg_enum_printer_dataex: Could not open key %s: %s\n",
2475 key
, win_errstr(result
)));
2479 result
= winreg_printer_enumvalues(tmp_ctx
,
2484 if (!W_ERROR_IS_OK(result
)) {
2485 DEBUG(0, ("winreg_enum_printer_dataex: Could not enumerate values in %s: %s\n",
2486 key
, win_errstr(result
)));
2490 *pnum_values
= num_values
;
2492 *penum_values
= talloc_move(mem_ctx
, &enum_values
);
2497 if (winreg_handle
!= NULL
) {
2500 if (is_valid_policy_hnd(&key_hnd
)) {
2501 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
2503 if (is_valid_policy_hnd(&hive_hnd
)) {
2504 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
2508 TALLOC_FREE(tmp_ctx
);
2512 /* Delete printer data over a winreg pipe. */
2513 WERROR
winreg_delete_printer_dataex(TALLOC_CTX
*mem_ctx
,
2514 const struct auth_serversupplied_info
*session_info
,
2515 struct messaging_context
*msg_ctx
,
2516 const char *printer
,
2520 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2521 struct dcerpc_binding_handle
*winreg_handle
= NULL
;
2522 struct policy_handle hive_hnd
, key_hnd
;
2523 struct winreg_String wvalue
= { 0, };
2525 WERROR result
= WERR_OK
;
2528 TALLOC_CTX
*tmp_ctx
;
2530 tmp_ctx
= talloc_stackframe();
2531 if (tmp_ctx
== NULL
) {
2535 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2537 TALLOC_FREE(tmp_ctx
);
2541 ZERO_STRUCT(hive_hnd
);
2542 ZERO_STRUCT(key_hnd
);
2544 result
= winreg_printer_openkey(tmp_ctx
,
2554 if (!W_ERROR_IS_OK(result
)) {
2555 DEBUG(0, ("winreg_delete_printer_dataex: Could not open key %s: %s\n",
2556 key
, win_errstr(result
)));
2560 wvalue
.name
= value
;
2561 status
= dcerpc_winreg_DeleteValue(winreg_handle
,
2566 if (!NT_STATUS_IS_OK(status
)) {
2567 DEBUG(0, ("winreg_delete_printer_dataex: Could not delete value %s: %s\n",
2568 value
, nt_errstr(status
)));
2569 result
= ntstatus_to_werror(status
);
2573 if (winreg_handle
!= NULL
) {
2576 if (is_valid_policy_hnd(&key_hnd
)) {
2577 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
2579 if (is_valid_policy_hnd(&hive_hnd
)) {
2580 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
2584 TALLOC_FREE(tmp_ctx
);
2588 /* Enumerate on the subkeys of a given key and provide the data. */
2589 WERROR
winreg_enum_printer_key(TALLOC_CTX
*mem_ctx
,
2590 const struct auth_serversupplied_info
*session_info
,
2591 struct messaging_context
*msg_ctx
,
2592 const char *printer
,
2594 uint32_t *pnum_subkeys
,
2595 const char ***psubkeys
)
2597 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2598 struct dcerpc_binding_handle
*winreg_handle
= NULL
;
2599 struct policy_handle hive_hnd
, key_hnd
;
2601 const char **subkeys
= NULL
;
2602 uint32_t num_subkeys
= -1;
2604 WERROR result
= WERR_OK
;
2607 TALLOC_CTX
*tmp_ctx
;
2609 tmp_ctx
= talloc_stackframe();
2610 if (tmp_ctx
== NULL
) {
2614 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2616 TALLOC_FREE(tmp_ctx
);
2620 ZERO_STRUCT(hive_hnd
);
2621 ZERO_STRUCT(key_hnd
);
2623 result
= winreg_printer_openkey(tmp_ctx
,
2633 if (!W_ERROR_IS_OK(result
)) {
2634 DEBUG(2, ("winreg_enum_printer_key: Could not open key %s: %s\n",
2635 key
, win_errstr(result
)));
2639 status
= dcerpc_winreg_enum_keys(tmp_ctx
,
2645 if (!NT_STATUS_IS_OK(status
)) {
2646 result
= ntstatus_to_werror(status
);
2648 if (!W_ERROR_IS_OK(result
)) {
2649 DEBUG(0, ("winreg_enum_printer_key: Could not enumerate subkeys in %s: %s\n",
2650 key
, win_errstr(result
)));
2654 *pnum_subkeys
= num_subkeys
;
2656 *psubkeys
= talloc_move(mem_ctx
, &subkeys
);
2661 if (winreg_handle
!= NULL
) {
2664 if (is_valid_policy_hnd(&key_hnd
)) {
2665 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
2667 if (is_valid_policy_hnd(&hive_hnd
)) {
2668 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
2672 TALLOC_FREE(tmp_ctx
);
2676 /* Delete a key with subkeys of a given printer. */
2677 WERROR
winreg_delete_printer_key(TALLOC_CTX
*mem_ctx
,
2678 const struct auth_serversupplied_info
*session_info
,
2679 struct messaging_context
*msg_ctx
,
2680 const char *printer
,
2683 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2684 struct dcerpc_binding_handle
*winreg_handle
= NULL
;
2685 struct policy_handle hive_hnd
, key_hnd
;
2689 TALLOC_CTX
*tmp_ctx
;
2691 tmp_ctx
= talloc_stackframe();
2692 if (tmp_ctx
== NULL
) {
2696 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2698 TALLOC_FREE(tmp_ctx
);
2702 result
= winreg_printer_openkey(tmp_ctx
,
2712 if (!W_ERROR_IS_OK(result
)) {
2713 /* key doesn't exist */
2714 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
2719 DEBUG(0, ("winreg_delete_printer_key: Could not open key %s: %s\n",
2720 key
, win_errstr(result
)));
2724 if (is_valid_policy_hnd(&key_hnd
)) {
2725 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &result
);
2728 if (key
== NULL
|| key
[0] == '\0') {
2731 keyname
= talloc_asprintf(tmp_ctx
,
2735 if (keyname
== NULL
) {
2736 result
= WERR_NOMEM
;
2741 result
= winreg_printer_delete_subkeys(tmp_ctx
,
2746 if (!W_ERROR_IS_OK(result
)) {
2747 DEBUG(0, ("winreg_delete_printer_key: Could not delete key %s: %s\n",
2748 key
, win_errstr(result
)));
2753 if (winreg_handle
!= NULL
) {
2756 if (is_valid_policy_hnd(&key_hnd
)) {
2757 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
2759 if (is_valid_policy_hnd(&hive_hnd
)) {
2760 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
2764 TALLOC_FREE(tmp_ctx
);
2768 WERROR
winreg_printer_update_changeid(TALLOC_CTX
*mem_ctx
,
2769 const struct auth_serversupplied_info
*session_info
,
2770 struct messaging_context
*msg_ctx
,
2771 const char *printer
)
2773 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2774 struct dcerpc_binding_handle
*winreg_handle
= NULL
;
2775 struct policy_handle hive_hnd
, key_hnd
;
2779 TALLOC_CTX
*tmp_ctx
;
2781 tmp_ctx
= talloc_stackframe();
2782 if (tmp_ctx
== NULL
) {
2786 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2788 TALLOC_FREE(tmp_ctx
);
2792 ZERO_STRUCT(hive_hnd
);
2793 ZERO_STRUCT(key_hnd
);
2795 result
= winreg_printer_openkey(tmp_ctx
,
2805 if (!W_ERROR_IS_OK(result
)) {
2806 DEBUG(0, ("winreg_printer_update_changeid: Could not open key %s: %s\n",
2807 path
, win_errstr(result
)));
2811 status
= dcerpc_winreg_set_dword(tmp_ctx
,
2815 winreg_printer_rev_changeid(),
2817 if (!NT_STATUS_IS_OK(status
)) {
2818 result
= ntstatus_to_werror(status
);
2820 if (!W_ERROR_IS_OK(result
)) {
2826 if (winreg_handle
!= NULL
) {
2829 if (is_valid_policy_hnd(&key_hnd
)) {
2830 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
2832 if (is_valid_policy_hnd(&hive_hnd
)) {
2833 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
2837 TALLOC_FREE(tmp_ctx
);
2841 WERROR
winreg_printer_get_changeid(TALLOC_CTX
*mem_ctx
,
2842 const struct auth_serversupplied_info
*session_info
,
2843 struct messaging_context
*msg_ctx
,
2844 const char *printer
,
2845 uint32_t *pchangeid
)
2847 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2848 struct dcerpc_binding_handle
*winreg_handle
= NULL
;
2849 struct policy_handle hive_hnd
, key_hnd
;
2850 uint32_t changeid
= 0;
2854 TALLOC_CTX
*tmp_ctx
;
2856 tmp_ctx
= talloc_stackframe();
2857 if (tmp_ctx
== NULL
) {
2861 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2863 TALLOC_FREE(tmp_ctx
);
2867 ZERO_STRUCT(hive_hnd
);
2868 ZERO_STRUCT(key_hnd
);
2870 result
= winreg_printer_openkey(tmp_ctx
,
2880 if (!W_ERROR_IS_OK(result
)) {
2881 DEBUG(2, ("winreg_printer_get_changeid: Could not open key %s: %s\n",
2882 path
, win_errstr(result
)));
2886 DEBUG(10, ("winreg_printer_get_changeid: get changeid from %s\n", path
));
2888 status
= dcerpc_winreg_query_dword(tmp_ctx
,
2894 if (!NT_STATUS_IS_OK(status
)) {
2895 result
= ntstatus_to_werror(status
);
2897 if (!W_ERROR_IS_OK(result
)) {
2902 *pchangeid
= changeid
;
2907 if (winreg_handle
!= NULL
) {
2910 if (is_valid_policy_hnd(&key_hnd
)) {
2911 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
2913 if (is_valid_policy_hnd(&hive_hnd
)) {
2914 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
2918 TALLOC_FREE(tmp_ctx
);
2923 * The special behaviour of the spoolss forms is documented at the website:
2925 * Managing Win32 Printserver Forms
2926 * http://unixwiz.net/techtips/winspooler-forms.html
2929 WERROR
winreg_printer_addform1(TALLOC_CTX
*mem_ctx
,
2930 const struct auth_serversupplied_info
*session_info
,
2931 struct messaging_context
*msg_ctx
,
2932 struct spoolss_AddFormInfo1
*form
)
2934 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2935 struct dcerpc_binding_handle
*winreg_handle
= NULL
;
2936 struct policy_handle hive_hnd
, key_hnd
;
2937 struct winreg_String wvalue
= { 0, };
2939 uint32_t num_info
= 0;
2940 union spoolss_FormInfo
*info
= NULL
;
2944 TALLOC_CTX
*tmp_ctx
;
2946 tmp_ctx
= talloc_stackframe();
2947 if (tmp_ctx
== NULL
) {
2951 ZERO_STRUCT(hive_hnd
);
2952 ZERO_STRUCT(key_hnd
);
2954 result
= winreg_printer_openkey(tmp_ctx
,
2958 TOP_LEVEL_CONTROL_FORMS_KEY
,
2964 if (!W_ERROR_IS_OK(result
)) {
2965 DEBUG(0, ("winreg_printer_addform1: Could not open key %s: %s\n",
2966 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
2970 result
= winreg_printer_enumforms1(tmp_ctx
, session_info
, msg_ctx
,
2972 if (!W_ERROR_IS_OK(result
)) {
2973 DEBUG(0, ("winreg_printer_addform: Could not enum keys %s: %s\n",
2974 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
2978 /* If form name already exists or is builtin return ALREADY_EXISTS */
2979 for (i
= 0; i
< num_info
; i
++) {
2980 if (strequal(info
[i
].info1
.form_name
, form
->form_name
)) {
2981 result
= WERR_FILE_EXISTS
;
2986 wvalue
.name
= form
->form_name
;
2988 blob
= data_blob_talloc(tmp_ctx
, NULL
, 32);
2989 SIVAL(blob
.data
, 0, form
->size
.width
);
2990 SIVAL(blob
.data
, 4, form
->size
.height
);
2991 SIVAL(blob
.data
, 8, form
->area
.left
);
2992 SIVAL(blob
.data
, 12, form
->area
.top
);
2993 SIVAL(blob
.data
, 16, form
->area
.right
);
2994 SIVAL(blob
.data
, 20, form
->area
.bottom
);
2995 SIVAL(blob
.data
, 24, num_info
+ 1); /* FIXME */
2996 SIVAL(blob
.data
, 28, form
->flags
);
2998 status
= dcerpc_winreg_SetValue(winreg_handle
,
3006 if (!NT_STATUS_IS_OK(status
)) {
3007 DEBUG(0, ("winreg_printer_addform1: Could not set value %s: %s\n",
3008 wvalue
.name
, nt_errstr(status
)));
3009 result
= ntstatus_to_werror(status
);
3013 if (winreg_handle
!= NULL
) {
3016 if (is_valid_policy_hnd(&key_hnd
)) {
3017 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
3019 if (is_valid_policy_hnd(&hive_hnd
)) {
3020 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
3025 TALLOC_FREE(tmp_ctx
);
3029 WERROR
winreg_printer_enumforms1(TALLOC_CTX
*mem_ctx
,
3030 const struct auth_serversupplied_info
*session_info
,
3031 struct messaging_context
*msg_ctx
,
3032 uint32_t *pnum_info
,
3033 union spoolss_FormInfo
**pinfo
)
3035 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3036 struct dcerpc_binding_handle
*winreg_handle
= NULL
;
3037 struct policy_handle hive_hnd
, key_hnd
;
3038 union spoolss_FormInfo
*info
;
3039 struct spoolss_PrinterEnumValues
*enum_values
= NULL
;
3040 uint32_t num_values
= 0;
3041 uint32_t num_builtin
= ARRAY_SIZE(builtin_forms1
);
3044 TALLOC_CTX
*tmp_ctx
;
3046 tmp_ctx
= talloc_stackframe();
3047 if (tmp_ctx
== NULL
) {
3051 ZERO_STRUCT(hive_hnd
);
3052 ZERO_STRUCT(key_hnd
);
3054 result
= winreg_printer_openkey(tmp_ctx
,
3058 TOP_LEVEL_CONTROL_FORMS_KEY
,
3064 if (!W_ERROR_IS_OK(result
)) {
3065 /* key doesn't exist */
3066 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
3071 DEBUG(0, ("winreg_printer_enumforms1: Could not open key %s: %s\n",
3072 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3076 result
= winreg_printer_enumvalues(tmp_ctx
,
3081 if (!W_ERROR_IS_OK(result
)) {
3082 DEBUG(0, ("winreg_printer_enumforms1: Could not enumerate values in %s: %s\n",
3083 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3087 info
= TALLOC_ARRAY(tmp_ctx
, union spoolss_FormInfo
, num_builtin
+ num_values
);
3089 result
= WERR_NOMEM
;
3093 /* Enumerate BUILTIN forms */
3094 for (i
= 0; i
< num_builtin
; i
++) {
3095 info
[i
].info1
= builtin_forms1
[i
];
3098 /* Enumerate registry forms */
3099 for (i
= 0; i
< num_values
; i
++) {
3100 union spoolss_FormInfo val
;
3102 if (enum_values
[i
].type
!= REG_BINARY
||
3103 enum_values
[i
].data_length
!= 32) {
3107 val
.info1
.form_name
= talloc_strdup(info
, enum_values
[i
].value_name
);
3108 if (val
.info1
.form_name
== NULL
) {
3109 result
= WERR_NOMEM
;
3113 val
.info1
.size
.width
= IVAL(enum_values
[i
].data
->data
, 0);
3114 val
.info1
.size
.height
= IVAL(enum_values
[i
].data
->data
, 4);
3115 val
.info1
.area
.left
= IVAL(enum_values
[i
].data
->data
, 8);
3116 val
.info1
.area
.top
= IVAL(enum_values
[i
].data
->data
, 12);
3117 val
.info1
.area
.right
= IVAL(enum_values
[i
].data
->data
, 16);
3118 val
.info1
.area
.bottom
= IVAL(enum_values
[i
].data
->data
, 20);
3119 /* skip form index IVAL(enum_values[i].data->data, 24)));*/
3120 val
.info1
.flags
= (enum spoolss_FormFlags
) IVAL(enum_values
[i
].data
->data
, 28);
3122 info
[i
+ num_builtin
] = val
;
3125 *pnum_info
= num_builtin
+ num_values
;
3127 *pinfo
= talloc_move(mem_ctx
, &info
);
3131 if (winreg_handle
!= NULL
) {
3134 if (is_valid_policy_hnd(&key_hnd
)) {
3135 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
3137 if (is_valid_policy_hnd(&hive_hnd
)) {
3138 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
3142 TALLOC_FREE(enum_values
);
3143 TALLOC_FREE(tmp_ctx
);
3147 WERROR
winreg_printer_deleteform1(TALLOC_CTX
*mem_ctx
,
3148 const struct auth_serversupplied_info
*session_info
,
3149 struct messaging_context
*msg_ctx
,
3150 const char *form_name
)
3152 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3153 struct dcerpc_binding_handle
*winreg_handle
= NULL
;
3154 struct policy_handle hive_hnd
, key_hnd
;
3155 struct winreg_String wvalue
= { 0, };
3156 uint32_t num_builtin
= ARRAY_SIZE(builtin_forms1
);
3158 WERROR result
= WERR_OK
;
3160 TALLOC_CTX
*tmp_ctx
;
3162 for (i
= 0; i
< num_builtin
; i
++) {
3163 if (strequal(builtin_forms1
[i
].form_name
, form_name
)) {
3164 return WERR_INVALID_PARAMETER
;
3168 tmp_ctx
= talloc_stackframe();
3169 if (tmp_ctx
== NULL
) {
3173 ZERO_STRUCT(hive_hnd
);
3174 ZERO_STRUCT(key_hnd
);
3176 result
= winreg_printer_openkey(tmp_ctx
,
3180 TOP_LEVEL_CONTROL_FORMS_KEY
,
3186 if (!W_ERROR_IS_OK(result
)) {
3187 DEBUG(0, ("winreg_printer_deleteform1: Could not open key %s: %s\n",
3188 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3189 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
3190 result
= WERR_INVALID_FORM_NAME
;
3195 wvalue
.name
= form_name
;
3196 status
= dcerpc_winreg_DeleteValue(winreg_handle
,
3201 if (!NT_STATUS_IS_OK(status
)) {
3202 /* If the value doesn't exist, return WERR_INVALID_FORM_NAME */
3203 DEBUG(0, ("winreg_printer_delteform1: Could not delete value %s: %s\n",
3204 wvalue
.name
, nt_errstr(status
)));
3205 result
= ntstatus_to_werror(status
);
3209 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
3210 result
= WERR_INVALID_FORM_NAME
;
3214 if (winreg_handle
!= NULL
) {
3217 if (is_valid_policy_hnd(&key_hnd
)) {
3218 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
3220 if (is_valid_policy_hnd(&hive_hnd
)) {
3221 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
3225 TALLOC_FREE(tmp_ctx
);
3229 WERROR
winreg_printer_setform1(TALLOC_CTX
*mem_ctx
,
3230 const struct auth_serversupplied_info
*session_info
,
3231 struct messaging_context
*msg_ctx
,
3232 const char *form_name
,
3233 struct spoolss_AddFormInfo1
*form
)
3235 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3236 struct dcerpc_binding_handle
*winreg_handle
= NULL
;
3237 struct policy_handle hive_hnd
, key_hnd
;
3238 struct winreg_String wvalue
= { 0, };
3240 uint32_t num_builtin
= ARRAY_SIZE(builtin_forms1
);
3244 TALLOC_CTX
*tmp_ctx
= NULL
;
3246 for (i
= 0; i
< num_builtin
; i
++) {
3247 if (strequal(builtin_forms1
[i
].form_name
, form
->form_name
)) {
3248 result
= WERR_INVALID_PARAM
;
3253 tmp_ctx
= talloc_stackframe();
3254 if (tmp_ctx
== NULL
) {
3258 ZERO_STRUCT(hive_hnd
);
3259 ZERO_STRUCT(key_hnd
);
3261 result
= winreg_printer_openkey(tmp_ctx
,
3265 TOP_LEVEL_CONTROL_FORMS_KEY
,
3271 if (!W_ERROR_IS_OK(result
)) {
3272 DEBUG(0, ("winreg_printer_setform1: Could not open key %s: %s\n",
3273 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3277 /* If form_name != form->form_name then we renamed the form */
3278 if (strequal(form_name
, form
->form_name
)) {
3279 result
= winreg_printer_deleteform1(tmp_ctx
, session_info
,
3280 msg_ctx
, form_name
);
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
)));
3288 wvalue
.name
= form
->form_name
;
3290 blob
= data_blob_talloc(tmp_ctx
, NULL
, 32);
3291 SIVAL(blob
.data
, 0, form
->size
.width
);
3292 SIVAL(blob
.data
, 4, form
->size
.height
);
3293 SIVAL(blob
.data
, 8, form
->area
.left
);
3294 SIVAL(blob
.data
, 12, form
->area
.top
);
3295 SIVAL(blob
.data
, 16, form
->area
.right
);
3296 SIVAL(blob
.data
, 20, form
->area
.bottom
);
3297 SIVAL(blob
.data
, 24, 42);
3298 SIVAL(blob
.data
, 28, form
->flags
);
3300 status
= dcerpc_winreg_SetValue(winreg_handle
,
3308 if (!NT_STATUS_IS_OK(status
)) {
3309 DEBUG(0, ("winreg_printer_setform1: Could not set value %s: %s\n",
3310 wvalue
.name
, nt_errstr(status
)));
3311 result
= ntstatus_to_werror(status
);
3315 if (winreg_handle
!= NULL
) {
3318 if (is_valid_policy_hnd(&key_hnd
)) {
3319 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
3321 if (is_valid_policy_hnd(&hive_hnd
)) {
3322 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
3326 TALLOC_FREE(tmp_ctx
);
3330 WERROR
winreg_printer_getform1(TALLOC_CTX
*mem_ctx
,
3331 const struct auth_serversupplied_info
*session_info
,
3332 struct messaging_context
*msg_ctx
,
3333 const char *form_name
,
3334 struct spoolss_FormInfo1
*r
)
3336 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3337 struct dcerpc_binding_handle
*winreg_handle
= NULL
;
3338 struct policy_handle hive_hnd
, key_hnd
;
3339 struct winreg_String wvalue
;
3340 enum winreg_Type type_in
= REG_NONE
;
3341 uint8_t *data_in
= NULL
;
3342 uint32_t data_in_size
= 0;
3343 uint32_t value_len
= 0;
3344 uint32_t num_builtin
= ARRAY_SIZE(builtin_forms1
);
3348 TALLOC_CTX
*tmp_ctx
;
3350 /* check builtin forms first */
3351 for (i
= 0; i
< num_builtin
; i
++) {
3352 if (strequal(builtin_forms1
[i
].form_name
, form_name
)) {
3353 *r
= builtin_forms1
[i
];
3358 tmp_ctx
= talloc_stackframe();
3359 if (tmp_ctx
== NULL
) {
3363 ZERO_STRUCT(hive_hnd
);
3364 ZERO_STRUCT(key_hnd
);
3366 result
= winreg_printer_openkey(tmp_ctx
,
3370 TOP_LEVEL_CONTROL_FORMS_KEY
,
3376 if (!W_ERROR_IS_OK(result
)) {
3377 DEBUG(2, ("winreg_printer_getform1: Could not open key %s: %s\n",
3378 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3382 wvalue
.name
= form_name
;
3385 * call QueryValue once with data == NULL to get the
3386 * needed memory size to be allocated, then allocate
3387 * data buffer and call again.
3389 status
= dcerpc_winreg_QueryValue(winreg_handle
,
3398 if (!NT_STATUS_IS_OK(status
)) {
3399 DEBUG(0, ("winreg_printer_getform1: Could not query value %s: %s\n",
3400 wvalue
.name
, nt_errstr(status
)));
3401 result
= ntstatus_to_werror(status
);
3404 if (!W_ERROR_IS_OK(result
)) {
3408 data_in
= (uint8_t *) TALLOC(tmp_ctx
, data_in_size
);
3409 if (data_in
== NULL
) {
3410 result
= WERR_NOMEM
;
3415 status
= dcerpc_winreg_QueryValue(winreg_handle
,
3424 if (!NT_STATUS_IS_OK(status
)) {
3425 DEBUG(0, ("winreg_printer_getform1: Could not query value %s: %s\n",
3426 wvalue
.name
, nt_errstr(status
)));
3427 result
= ntstatus_to_werror(status
);
3430 if (!W_ERROR_IS_OK(result
)) {
3434 r
->form_name
= talloc_strdup(mem_ctx
, form_name
);
3435 if (r
->form_name
== NULL
) {
3436 result
= WERR_NOMEM
;
3440 r
->size
.width
= IVAL(data_in
, 0);
3441 r
->size
.height
= IVAL(data_in
, 4);
3442 r
->area
.left
= IVAL(data_in
, 8);
3443 r
->area
.top
= IVAL(data_in
, 12);
3444 r
->area
.right
= IVAL(data_in
, 16);
3445 r
->area
.bottom
= IVAL(data_in
, 20);
3446 /* skip index IVAL(data_in, 24)));*/
3447 r
->flags
= (enum spoolss_FormFlags
) IVAL(data_in
, 28);
3451 if (winreg_handle
!= NULL
) {
3454 if (is_valid_policy_hnd(&key_hnd
)) {
3455 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
3457 if (is_valid_policy_hnd(&hive_hnd
)) {
3458 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
3462 TALLOC_FREE(tmp_ctx
);
3466 WERROR
winreg_add_driver(TALLOC_CTX
*mem_ctx
,
3467 const struct auth_serversupplied_info
*session_info
,
3468 struct messaging_context
*msg_ctx
,
3469 struct spoolss_AddDriverInfoCtr
*r
,
3470 const char **driver_name
,
3471 uint32_t *driver_version
)
3473 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3474 struct dcerpc_binding_handle
*winreg_handle
= NULL
;
3475 struct policy_handle hive_hnd
, key_hnd
;
3476 struct spoolss_DriverInfo8 info8
;
3477 TALLOC_CTX
*tmp_ctx
= NULL
;
3481 ZERO_STRUCT(hive_hnd
);
3482 ZERO_STRUCT(key_hnd
);
3485 if (!driver_info_ctr_to_info8(r
, &info8
)) {
3486 result
= WERR_INVALID_PARAMETER
;
3490 tmp_ctx
= talloc_stackframe();
3491 if (tmp_ctx
== NULL
) {
3495 result
= winreg_printer_opendriver(tmp_ctx
,
3505 if (!W_ERROR_IS_OK(result
)) {
3506 DEBUG(0, ("winreg_add_driver: "
3507 "Could not open driver key (%s,%s,%d): %s\n",
3508 info8
.driver_name
, info8
.architecture
,
3509 info8
.version
, win_errstr(result
)));
3513 /* TODO: "Attributes" ? */
3515 status
= dcerpc_winreg_set_dword(tmp_ctx
,
3521 if (!NT_STATUS_IS_OK(status
)) {
3522 result
= ntstatus_to_werror(status
);
3524 if (!W_ERROR_IS_OK(result
)) {
3528 status
= dcerpc_winreg_set_sz(tmp_ctx
,
3534 if (!NT_STATUS_IS_OK(status
)) {
3535 result
= ntstatus_to_werror(status
);
3537 if (!W_ERROR_IS_OK(result
)) {
3541 status
= dcerpc_winreg_set_sz(tmp_ctx
,
3547 if (!NT_STATUS_IS_OK(status
)) {
3548 result
= ntstatus_to_werror(status
);
3550 if (!W_ERROR_IS_OK(result
)) {
3554 status
= dcerpc_winreg_set_sz(tmp_ctx
,
3557 "Configuration File",
3560 if (!NT_STATUS_IS_OK(status
)) {
3561 result
= ntstatus_to_werror(status
);
3563 if (!W_ERROR_IS_OK(result
)) {
3567 status
= dcerpc_winreg_set_sz(tmp_ctx
,
3573 if (!NT_STATUS_IS_OK(status
)) {
3574 result
= ntstatus_to_werror(status
);
3576 if (!W_ERROR_IS_OK(result
)) {
3580 status
= dcerpc_winreg_set_multi_sz(tmp_ctx
,
3584 info8
.dependent_files
,
3586 if (!NT_STATUS_IS_OK(status
)) {
3587 result
= ntstatus_to_werror(status
);
3589 if (!W_ERROR_IS_OK(result
)) {
3593 status
= dcerpc_winreg_set_sz(tmp_ctx
,
3599 if (!NT_STATUS_IS_OK(status
)) {
3600 result
= ntstatus_to_werror(status
);
3602 if (!W_ERROR_IS_OK(result
)) {
3606 status
= dcerpc_winreg_set_sz(tmp_ctx
,
3610 info8
.default_datatype
,
3612 if (!NT_STATUS_IS_OK(status
)) {
3613 result
= ntstatus_to_werror(status
);
3615 if (!W_ERROR_IS_OK(result
)) {
3619 status
= dcerpc_winreg_set_multi_sz(tmp_ctx
,
3621 &key_hnd
, "Previous Names",
3622 info8
.previous_names
,
3624 if (!NT_STATUS_IS_OK(status
)) {
3625 result
= ntstatus_to_werror(status
);
3627 if (!W_ERROR_IS_OK(result
)) {
3631 result
= winreg_printer_write_date(tmp_ctx
, winreg_handle
,
3632 &key_hnd
, "DriverDate",
3634 if (!W_ERROR_IS_OK(result
)) {
3638 result
= winreg_printer_write_ver(tmp_ctx
, winreg_handle
,
3639 &key_hnd
, "DriverVersion",
3640 info8
.driver_version
);
3641 if (!W_ERROR_IS_OK(result
)) {
3645 status
= dcerpc_winreg_set_sz(tmp_ctx
,
3649 info8
.manufacturer_name
,
3651 if (!NT_STATUS_IS_OK(status
)) {
3652 result
= ntstatus_to_werror(status
);
3654 if (!W_ERROR_IS_OK(result
)) {
3658 status
= dcerpc_winreg_set_sz(tmp_ctx
,
3662 info8
.manufacturer_url
,
3664 if (!NT_STATUS_IS_OK(status
)) {
3665 result
= ntstatus_to_werror(status
);
3667 if (!W_ERROR_IS_OK(result
)) {
3671 status
= dcerpc_winreg_set_sz(tmp_ctx
,
3677 if (!NT_STATUS_IS_OK(status
)) {
3678 result
= ntstatus_to_werror(status
);
3680 if (!W_ERROR_IS_OK(result
)) {
3684 status
= dcerpc_winreg_set_sz(tmp_ctx
,
3690 if (!NT_STATUS_IS_OK(status
)) {
3691 result
= ntstatus_to_werror(status
);
3693 if (!W_ERROR_IS_OK(result
)) {
3697 status
= dcerpc_winreg_set_sz(tmp_ctx
,
3701 info8
.print_processor
,
3703 if (!NT_STATUS_IS_OK(status
)) {
3704 result
= ntstatus_to_werror(status
);
3706 if (!W_ERROR_IS_OK(result
)) {
3710 status
= dcerpc_winreg_set_sz(tmp_ctx
,
3716 if (!NT_STATUS_IS_OK(status
)) {
3717 result
= ntstatus_to_werror(status
);
3719 if (!W_ERROR_IS_OK(result
)) {
3723 status
= dcerpc_winreg_set_multi_sz(tmp_ctx
,
3727 info8
.color_profiles
,
3729 if (!NT_STATUS_IS_OK(status
)) {
3730 result
= ntstatus_to_werror(status
);
3732 if (!W_ERROR_IS_OK(result
)) {
3736 status
= dcerpc_winreg_set_sz(tmp_ctx
,
3742 if (!NT_STATUS_IS_OK(status
)) {
3743 result
= ntstatus_to_werror(status
);
3745 if (!W_ERROR_IS_OK(result
)) {
3749 status
= dcerpc_winreg_set_dword(tmp_ctx
,
3752 "PrinterDriverAttributes",
3753 info8
.printer_driver_attributes
,
3755 if (!NT_STATUS_IS_OK(status
)) {
3756 result
= ntstatus_to_werror(status
);
3758 if (!W_ERROR_IS_OK(result
)) {
3762 status
= dcerpc_winreg_set_multi_sz(tmp_ctx
,
3766 info8
.core_driver_dependencies
,
3768 if (!NT_STATUS_IS_OK(status
)) {
3769 result
= ntstatus_to_werror(status
);
3771 if (!W_ERROR_IS_OK(result
)) {
3775 result
= winreg_printer_write_date(tmp_ctx
, winreg_handle
,
3776 &key_hnd
, "MinInboxDriverVerDate",
3777 info8
.min_inbox_driver_ver_date
);
3778 if (!W_ERROR_IS_OK(result
)) {
3782 result
= winreg_printer_write_ver(tmp_ctx
, winreg_handle
, &key_hnd
,
3783 "MinInboxDriverVerVersion",
3784 info8
.min_inbox_driver_ver_version
);
3785 if (!W_ERROR_IS_OK(result
)) {
3789 *driver_name
= info8
.driver_name
;
3790 *driver_version
= info8
.version
;
3793 if (winreg_handle
!= NULL
) {
3796 if (is_valid_policy_hnd(&key_hnd
)) {
3797 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
3799 if (is_valid_policy_hnd(&hive_hnd
)) {
3800 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
3804 TALLOC_FREE(tmp_ctx
);
3808 WERROR
winreg_get_driver(TALLOC_CTX
*mem_ctx
,
3809 const struct auth_serversupplied_info
*session_info
,
3810 struct messaging_context
*msg_ctx
,
3811 const char *architecture
,
3812 const char *driver_name
,
3813 uint32_t driver_version
,
3814 struct spoolss_DriverInfo8
**_info8
)
3816 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3817 struct dcerpc_binding_handle
*winreg_handle
= NULL
;
3818 struct policy_handle hive_hnd
, key_hnd
;
3819 struct spoolss_DriverInfo8 i8
, *info8
;
3820 struct spoolss_PrinterEnumValues
*enum_values
= NULL
;
3821 struct spoolss_PrinterEnumValues
*v
;
3822 uint32_t num_values
= 0;
3823 TALLOC_CTX
*tmp_ctx
;
3827 ZERO_STRUCT(hive_hnd
);
3828 ZERO_STRUCT(key_hnd
);
3831 tmp_ctx
= talloc_stackframe();
3832 if (tmp_ctx
== NULL
) {
3836 if (driver_version
== DRIVER_ANY_VERSION
) {
3837 /* look for Win2k first and then for NT4 */
3838 result
= winreg_printer_opendriver(tmp_ctx
,
3848 if (!W_ERROR_IS_OK(result
)) {
3849 result
= winreg_printer_opendriver(tmp_ctx
,
3861 /* ok normal case */
3862 result
= winreg_printer_opendriver(tmp_ctx
,
3873 if (!W_ERROR_IS_OK(result
)) {
3874 DEBUG(5, ("winreg_get_driver: "
3875 "Could not open driver key (%s,%s,%d): %s\n",
3876 driver_name
, architecture
,
3877 driver_version
, win_errstr(result
)));
3881 result
= winreg_printer_enumvalues(tmp_ctx
,
3886 if (!W_ERROR_IS_OK(result
)) {
3887 DEBUG(0, ("winreg_get_driver: "
3888 "Could not enumerate values for (%s,%s,%d): %s\n",
3889 driver_name
, architecture
,
3890 driver_version
, win_errstr(result
)));
3894 info8
= talloc_zero(tmp_ctx
, struct spoolss_DriverInfo8
);
3895 if (info8
== NULL
) {
3896 result
= WERR_NOMEM
;
3900 info8
->driver_name
= talloc_strdup(info8
, driver_name
);
3901 if (info8
->driver_name
== NULL
) {
3902 result
= WERR_NOMEM
;
3906 info8
->architecture
= talloc_strdup(info8
, architecture
);
3907 if (info8
->architecture
== NULL
) {
3908 result
= WERR_NOMEM
;
3914 for (i
= 0; i
< num_values
; i
++) {
3915 const char *tmp_str
;
3918 v
= &enum_values
[i
];
3920 result
= winreg_enumval_to_dword(info8
, v
,
3923 if (NT_STATUS_IS_OK(result
)) {
3924 info8
->version
= (enum spoolss_DriverOSVersion
) tmp
;
3926 CHECK_ERROR(result
);
3928 result
= winreg_enumval_to_sz(info8
, v
,
3930 &info8
->driver_path
);
3931 CHECK_ERROR(result
);
3933 result
= winreg_enumval_to_sz(info8
, v
,
3936 CHECK_ERROR(result
);
3938 result
= winreg_enumval_to_sz(info8
, v
,
3939 "Configuration File",
3940 &info8
->config_file
);
3941 CHECK_ERROR(result
);
3943 result
= winreg_enumval_to_sz(info8
, v
,
3946 CHECK_ERROR(result
);
3948 result
= winreg_enumval_to_multi_sz(info8
, v
,
3950 &info8
->dependent_files
);
3951 CHECK_ERROR(result
);
3953 result
= winreg_enumval_to_sz(info8
, v
,
3955 &info8
->monitor_name
);
3956 CHECK_ERROR(result
);
3958 result
= winreg_enumval_to_sz(info8
, v
,
3960 &info8
->default_datatype
);
3961 CHECK_ERROR(result
);
3963 result
= winreg_enumval_to_multi_sz(info8
, v
,
3965 &info8
->previous_names
);
3966 CHECK_ERROR(result
);
3968 result
= winreg_enumval_to_sz(info8
, v
,
3971 if (W_ERROR_IS_OK(result
)) {
3972 result
= winreg_printer_date_to_NTTIME(tmp_str
,
3973 &info8
->driver_date
);
3975 CHECK_ERROR(result
);
3977 result
= winreg_enumval_to_sz(info8
, v
,
3980 if (W_ERROR_IS_OK(result
)) {
3981 result
= winreg_printer_ver_to_dword(tmp_str
,
3982 &info8
->driver_version
);
3984 CHECK_ERROR(result
);
3986 result
= winreg_enumval_to_sz(info8
, v
,
3988 &info8
->manufacturer_name
);
3989 CHECK_ERROR(result
);
3991 result
= winreg_enumval_to_sz(info8
, v
,
3993 &info8
->manufacturer_url
);
3994 CHECK_ERROR(result
);
3996 result
= winreg_enumval_to_sz(info8
, v
,
3998 &info8
->hardware_id
);
3999 CHECK_ERROR(result
);
4001 result
= winreg_enumval_to_sz(info8
, v
,
4004 CHECK_ERROR(result
);
4006 result
= winreg_enumval_to_sz(info8
, v
,
4008 &info8
->print_processor
);
4009 CHECK_ERROR(result
);
4011 result
= winreg_enumval_to_sz(info8
, v
,
4013 &info8
->vendor_setup
);
4014 CHECK_ERROR(result
);
4016 result
= winreg_enumval_to_multi_sz(info8
, v
,
4018 &info8
->color_profiles
);
4019 CHECK_ERROR(result
);
4021 result
= winreg_enumval_to_sz(info8
, v
,
4024 CHECK_ERROR(result
);
4026 result
= winreg_enumval_to_dword(info8
, v
,
4027 "PrinterDriverAttributes",
4028 &info8
->printer_driver_attributes
);
4029 CHECK_ERROR(result
);
4031 result
= winreg_enumval_to_multi_sz(info8
, v
,
4033 &info8
->core_driver_dependencies
);
4034 CHECK_ERROR(result
);
4036 result
= winreg_enumval_to_sz(info8
, v
,
4037 "MinInboxDriverVerDate",
4039 if (W_ERROR_IS_OK(result
)) {
4040 result
= winreg_printer_date_to_NTTIME(tmp_str
,
4041 &info8
->min_inbox_driver_ver_date
);
4043 CHECK_ERROR(result
);
4045 result
= winreg_enumval_to_sz(info8
, v
,
4046 "MinInboxDriverVerVersion",
4048 if (W_ERROR_IS_OK(result
)) {
4049 result
= winreg_printer_ver_to_dword(tmp_str
,
4050 &info8
->min_inbox_driver_ver_version
);
4052 CHECK_ERROR(result
);
4055 if (!W_ERROR_IS_OK(result
)) {
4056 DEBUG(0, ("winreg_enumval_to_TYPE() failed "
4057 "for %s: %s\n", v
->value_name
,
4058 win_errstr(result
)));
4062 *_info8
= talloc_steal(mem_ctx
, info8
);
4065 if (winreg_handle
!= NULL
) {
4068 if (is_valid_policy_hnd(&key_hnd
)) {
4069 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
4071 if (is_valid_policy_hnd(&hive_hnd
)) {
4072 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
4076 TALLOC_FREE(tmp_ctx
);
4080 WERROR
winreg_del_driver(TALLOC_CTX
*mem_ctx
,
4081 const struct auth_serversupplied_info
*session_info
,
4082 struct messaging_context
*msg_ctx
,
4083 struct spoolss_DriverInfo8
*info8
,
4086 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4087 struct dcerpc_binding_handle
*winreg_handle
= NULL
;
4088 struct policy_handle hive_hnd
, key_hnd
;
4089 TALLOC_CTX
*tmp_ctx
;
4093 ZERO_STRUCT(hive_hnd
);
4094 ZERO_STRUCT(key_hnd
);
4096 tmp_ctx
= talloc_stackframe();
4097 if (tmp_ctx
== NULL
) {
4101 /* test that the key exists */
4102 result
= winreg_printer_opendriver(tmp_ctx
,
4106 info8
->architecture
,
4112 if (!W_ERROR_IS_OK(result
)) {
4113 /* key doesn't exist */
4114 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
4119 DEBUG(5, ("winreg_del_driver: "
4120 "Could not open driver (%s,%s,%u): %s\n",
4121 info8
->driver_name
, info8
->architecture
,
4122 version
, win_errstr(result
)));
4127 if (is_valid_policy_hnd(&key_hnd
)) {
4128 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &result
);
4131 key_name
= talloc_asprintf(tmp_ctx
,
4132 "%s\\Environments\\%s\\Drivers\\Version-%u\\%s",
4133 TOP_LEVEL_CONTROL_KEY
,
4134 info8
->architecture
, version
,
4135 info8
->driver_name
);
4136 if (key_name
== NULL
) {
4137 result
= WERR_NOMEM
;
4141 result
= winreg_printer_delete_subkeys(tmp_ctx
,
4146 if (!W_ERROR_IS_OK(result
)) {
4147 DEBUG(0, ("winreg_del_driver: "
4148 "Could not open driver (%s,%s,%u): %s\n",
4149 info8
->driver_name
, info8
->architecture
,
4150 version
, win_errstr(result
)));
4156 if (winreg_handle
!= NULL
) {
4159 if (is_valid_policy_hnd(&key_hnd
)) {
4160 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
4162 if (is_valid_policy_hnd(&hive_hnd
)) {
4163 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
4167 TALLOC_FREE(tmp_ctx
);
4171 WERROR
winreg_get_driver_list(TALLOC_CTX
*mem_ctx
,
4172 const struct auth_serversupplied_info
*session_info
,
4173 struct messaging_context
*msg_ctx
,
4174 const char *architecture
,
4176 uint32_t *num_drivers
,
4177 const char ***drivers_p
)
4179 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4180 struct dcerpc_binding_handle
*winreg_handle
= NULL
;
4181 struct policy_handle hive_hnd
, key_hnd
;
4182 const char **drivers
;
4183 TALLOC_CTX
*tmp_ctx
;
4190 ZERO_STRUCT(hive_hnd
);
4191 ZERO_STRUCT(key_hnd
);
4193 tmp_ctx
= talloc_stackframe();
4194 if (tmp_ctx
== NULL
) {
4198 /* use NULL for the driver name so we open the key that is
4199 * parent of all drivers for this architecture and version */
4200 result
= winreg_printer_opendriver(tmp_ctx
,
4210 if (!W_ERROR_IS_OK(result
)) {
4211 DEBUG(5, ("winreg_get_driver_list: "
4212 "Could not open key (%s,%u): %s\n",
4213 architecture
, version
, win_errstr(result
)));
4218 status
= dcerpc_winreg_enum_keys(tmp_ctx
,
4224 if (!NT_STATUS_IS_OK(status
)) {
4225 result
= ntstatus_to_werror(status
);
4227 if (!W_ERROR_IS_OK(result
)) {
4228 DEBUG(0, ("winreg_get_driver_list: "
4229 "Could not enumerate drivers for (%s,%u): %s\n",
4230 architecture
, version
, win_errstr(result
)));
4234 *drivers_p
= talloc_steal(mem_ctx
, drivers
);
4238 if (winreg_handle
!= NULL
) {
4241 if (is_valid_policy_hnd(&key_hnd
)) {
4242 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
4244 if (is_valid_policy_hnd(&hive_hnd
)) {
4245 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
4249 TALLOC_FREE(tmp_ctx
);