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 "srv_spoolss_util.h"
24 #include "../librpc/gen_ndr/ndr_spoolss.h"
25 #include "../librpc/gen_ndr/srv_winreg.h"
26 #include "../librpc/gen_ndr/cli_winreg.h"
27 #include "../librpc/gen_ndr/ndr_security.h"
29 #define TOP_LEVEL_PRINT_KEY "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print"
30 #define TOP_LEVEL_PRINT_PRINTERS_KEY TOP_LEVEL_PRINT_KEY "\\Printers"
31 #define TOP_LEVEL_CONTROL_KEY "SYSTEM\\CurrentControlSet\\Control\\Print"
32 #define TOP_LEVEL_CONTROL_FORMS_KEY TOP_LEVEL_CONTROL_KEY "\\Forms"
34 #define EMPTY_STRING ""
35 static const char *empty_string_array
[1] = { NULL
};
36 #define EMPTY_STRING_ARRAY empty_string_array
38 #define CHECK_ERROR(result) \
39 if (W_ERROR_IS_OK(result)) continue; \
40 if (W_ERROR_EQUAL(result, WERR_NOT_FOUND)) result = WERR_OK; \
41 if (!W_ERROR_IS_OK(result)) break
43 /* FLAGS, NAME, with, height, left, top, right, bottom */
44 static const struct spoolss_FormInfo1 builtin_forms1
[] = {
45 { SPOOLSS_FORM_BUILTIN
, "10x11", {0x3e030,0x44368}, {0x0,0x0,0x3e030,0x44368} },
46 { SPOOLSS_FORM_BUILTIN
, "10x14", {0x3e030,0x56d10}, {0x0,0x0,0x3e030,0x56d10} },
47 { SPOOLSS_FORM_BUILTIN
, "11x17", {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} },
48 { SPOOLSS_FORM_BUILTIN
, "12x11", {0x4a724,0x443e1}, {0x0,0x0,0x4a724,0x443e1} },
49 { SPOOLSS_FORM_BUILTIN
, "15x11", {0x5d048,0x44368}, {0x0,0x0,0x5d048,0x44368} },
50 { SPOOLSS_FORM_BUILTIN
, "6 3/4 Envelope", {0x167ab,0x284ec}, {0x0,0x0,0x167ab,0x284ec} },
51 { SPOOLSS_FORM_BUILTIN
, "9x11", {0x37cf8,0x44368}, {0x0,0x0,0x37cf8,0x44368} },
52 { SPOOLSS_FORM_BUILTIN
, "A0", {0xcd528,0x122488},{0x0,0x0,0xcd528,0x122488} },
53 { SPOOLSS_FORM_BUILTIN
, "A1", {0x91050,0xcd528}, {0x0,0x0,0x91050,0xcd528} },
54 { SPOOLSS_FORM_BUILTIN
, "A2", {0x668a0,0x91050}, {0x0,0x0,0x668a0,0x91050} },
55 { SPOOLSS_FORM_BUILTIN
, "A3 Extra Transverse", {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} },
56 { SPOOLSS_FORM_BUILTIN
, "A3 Extra", {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} },
57 { SPOOLSS_FORM_BUILTIN
, "A3 Rotated", {0x668a0,0x48828}, {0x0,0x0,0x668a0,0x48828} },
58 { SPOOLSS_FORM_BUILTIN
, "A3 Transverse", {0x48828,0x668a0}, {0x0,0x0,0x48828,0x668a0} },
59 { SPOOLSS_FORM_BUILTIN
, "A3", {0x48828,0x668a0}, {0x0,0x0,0x48828,0x668a0} },
60 { SPOOLSS_FORM_BUILTIN
, "A4 Extra", {0x397c2,0x4eb16}, {0x0,0x0,0x397c2,0x4eb16} },
61 { SPOOLSS_FORM_BUILTIN
, "A4 Plus", {0x33450,0x50910}, {0x0,0x0,0x33450,0x50910} },
62 { SPOOLSS_FORM_BUILTIN
, "A4 Rotated", {0x48828,0x33450}, {0x0,0x0,0x48828,0x33450} },
63 { SPOOLSS_FORM_BUILTIN
, "A4 Small", {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
64 { SPOOLSS_FORM_BUILTIN
, "A4 Transverse", {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
65 { SPOOLSS_FORM_BUILTIN
, "A4", {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
66 { SPOOLSS_FORM_BUILTIN
, "A5 Extra", {0x2a7b0,0x395f8}, {0x0,0x0,0x2a7b0,0x395f8} },
67 { SPOOLSS_FORM_BUILTIN
, "A5 Rotated", {0x33450,0x24220}, {0x0,0x0,0x33450,0x24220} },
68 { SPOOLSS_FORM_BUILTIN
, "A5 Transverse", {0x24220,0x33450}, {0x0,0x0,0x24220,0x33450} },
69 { SPOOLSS_FORM_BUILTIN
, "A5", {0x24220,0x33450}, {0x0,0x0,0x24220,0x33450} },
70 { SPOOLSS_FORM_BUILTIN
, "A6 Rotated", {0x24220,0x19a28}, {0x0,0x0,0x24220,0x19a28} },
71 { SPOOLSS_FORM_BUILTIN
, "A6", {0x19a28,0x24220}, {0x0,0x0,0x19a28,0x24220} },
72 { SPOOLSS_FORM_BUILTIN
, "B4 (ISO)", {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} },
73 { SPOOLSS_FORM_BUILTIN
, "B4 (JIS) Rotated", {0x58de0,0x3ebe8}, {0x0,0x0,0x58de0,0x3ebe8} },
74 { SPOOLSS_FORM_BUILTIN
, "B4 (JIS)", {0x3ebe8,0x58de0}, {0x0,0x0,0x3ebe8,0x58de0} },
75 { SPOOLSS_FORM_BUILTIN
, "B5 (ISO) Extra", {0x31128,0x43620}, {0x0,0x0,0x31128,0x43620} },
76 { SPOOLSS_FORM_BUILTIN
, "B5 (JIS) Rotated", {0x3ebe8,0x2c6f0}, {0x0,0x0,0x3ebe8,0x2c6f0} },
77 { SPOOLSS_FORM_BUILTIN
, "B5 (JIS) Transverse", {0x2c6f0,0x3ebe8}, {0x0,0x0,0x2c6f0,0x3ebe8} },
78 { SPOOLSS_FORM_BUILTIN
, "B5 (JIS)", {0x2c6f0,0x3ebe8}, {0x0,0x0,0x2c6f0,0x3ebe8} },
79 { SPOOLSS_FORM_BUILTIN
, "B6 (JIS) Rotated", {0x2c6f0,0x1f400}, {0x0,0x0,0x2c6f0,0x1f400} },
80 { SPOOLSS_FORM_BUILTIN
, "B6 (JIS)", {0x1f400,0x2c6f0}, {0x0,0x0,0x1f400,0x2c6f0} },
81 { SPOOLSS_FORM_BUILTIN
, "C size sheet", {0x696b8,0x886d0}, {0x0,0x0,0x696b8,0x886d0} },
82 { SPOOLSS_FORM_BUILTIN
, "D size sheet", {0x886d0,0xd2d70}, {0x0,0x0,0x886d0,0xd2d70} },
83 { SPOOLSS_FORM_BUILTIN
, "Double Japan Postcard Rotated", {0x24220,0x30d40}, {0x0,0x0,0x24220,0x30d40} },
84 { SPOOLSS_FORM_BUILTIN
, "E size sheet", {0xd2d70,0x110da0},{0x0,0x0,0xd2d70,0x110da0} },
85 { SPOOLSS_FORM_BUILTIN
, "Envelope #10", {0x19947,0x3ae94}, {0x0,0x0,0x19947,0x3ae94} },
86 { SPOOLSS_FORM_BUILTIN
, "Envelope #11", {0x1be7c,0x40565}, {0x0,0x0,0x1be7c,0x40565} },
87 { SPOOLSS_FORM_BUILTIN
, "Envelope #12", {0x1d74a,0x44368}, {0x0,0x0,0x1d74a,0x44368} },
88 { SPOOLSS_FORM_BUILTIN
, "Envelope #14", {0x1f018,0x47504}, {0x0,0x0,0x1f018,0x47504} },
89 { SPOOLSS_FORM_BUILTIN
, "Envelope #9", {0x18079,0x37091}, {0x0,0x0,0x18079,0x37091} },
90 { SPOOLSS_FORM_BUILTIN
, "Envelope B4", {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} },
91 { SPOOLSS_FORM_BUILTIN
, "Envelope B5", {0x2af80,0x3d090}, {0x0,0x0,0x2af80,0x3d090} },
92 { SPOOLSS_FORM_BUILTIN
, "Envelope B6", {0x2af80,0x1e848}, {0x0,0x0,0x2af80,0x1e848} },
93 { SPOOLSS_FORM_BUILTIN
, "Envelope C3", {0x4f1a0,0x6fd10}, {0x0,0x0,0x4f1a0,0x6fd10} },
94 { SPOOLSS_FORM_BUILTIN
, "Envelope C4", {0x37e88,0x4f1a0}, {0x0,0x0,0x37e88,0x4f1a0} },
95 { SPOOLSS_FORM_BUILTIN
, "Envelope C5", {0x278d0,0x37e88}, {0x0,0x0,0x278d0,0x37e88} },
96 { SPOOLSS_FORM_BUILTIN
, "Envelope C6", {0x1bd50,0x278d0}, {0x0,0x0,0x1bd50,0x278d0} },
97 { SPOOLSS_FORM_BUILTIN
, "Envelope C65", {0x1bd50,0x37e88}, {0x0,0x0,0x1bd50,0x37e88} },
98 { SPOOLSS_FORM_BUILTIN
, "Envelope DL", {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} },
99 { SPOOLSS_FORM_BUILTIN
, "Envelope Invite", {0x35b60,0x35b60}, {0x0,0x0,0x35b60,0x35b60} },
100 { SPOOLSS_FORM_BUILTIN
, "Envelope Monarch", {0x18079,0x2e824}, {0x0,0x0,0x18079,0x2e824} },
101 { SPOOLSS_FORM_BUILTIN
, "Envelope", {0x1adb0,0x38270}, {0x0,0x0,0x1adb0,0x38270} },
102 { SPOOLSS_FORM_BUILTIN
, "Executive", {0x2cf56,0x411cc}, {0x0,0x0,0x2cf56,0x411cc} },
103 { SPOOLSS_FORM_BUILTIN
, "Folio", {0x34b5c,0x509d8}, {0x0,0x0,0x34b5c,0x509d8} },
104 { SPOOLSS_FORM_BUILTIN
, "German Legal Fanfold", {0x34b5c,0x509d8}, {0x0,0x0,0x34b5c,0x509d8} },
105 { SPOOLSS_FORM_BUILTIN
, "German Std Fanfold", {0x34b5c,0x4a6a0}, {0x0,0x0,0x34b5c,0x4a6a0} },
106 { SPOOLSS_FORM_BUILTIN
, "Japan Envelope Chou #3 Rotated", {0x395f8,0x1d4c0}, {0x0,0x0,0x395f8,0x1d4c0} },
107 { SPOOLSS_FORM_BUILTIN
, "Japan Envelope Chou #4 Rotated", {0x320c8,0x15f90}, {0x0,0x0,0x320c8,0x15f90} },
108 { SPOOLSS_FORM_BUILTIN
, "Japan Envelope Kaku #2 Rotated", {0x510e0,0x3a980}, {0x0,0x0,0x510e0,0x3a980} },
109 { SPOOLSS_FORM_BUILTIN
, "Japan Envelope Kaku #3 Rotated", {0x43a08,0x34bc0}, {0x0,0x0,0x43a08,0x34bc0} },
110 { SPOOLSS_FORM_BUILTIN
, "Japan Envelope You #4 Rotated", {0x395f8,0x19a28}, {0x0,0x0,0x395f8,0x19a28} },
111 { SPOOLSS_FORM_BUILTIN
, "Japan Envelope You #4", {0x19a28,0x395f8}, {0x0,0x0,0x19a28,0x395f8} },
112 { SPOOLSS_FORM_BUILTIN
, "Japanese Double Postcard", {0x30d40,0x24220}, {0x0,0x0,0x30d40,0x24220} },
113 { SPOOLSS_FORM_BUILTIN
, "Japanese Envelope Chou #3", {0x1d4c0,0x395f8}, {0x0,0x0,0x1d4c0,0x395f8} },
114 { SPOOLSS_FORM_BUILTIN
, "Japanese Envelope Chou #4", {0x15f90,0x320c8}, {0x0,0x0,0x15f90,0x320c8} },
115 { SPOOLSS_FORM_BUILTIN
, "Japanese Envelope Kaku #2", {0x3a980,0x510e0}, {0x0,0x0,0x3a980,0x510e0} },
116 { SPOOLSS_FORM_BUILTIN
, "Japanese Envelope Kaku #3", {0x34bc0,0x43a08}, {0x0,0x0,0x34bc0,0x43a08} },
117 { SPOOLSS_FORM_BUILTIN
, "Japanese Postcard Rotated", {0x24220,0x186a0}, {0x0,0x0,0x24220,0x186a0} },
118 { SPOOLSS_FORM_BUILTIN
, "Japanese Postcard", {0x186a0,0x24220}, {0x0,0x0,0x186a0,0x24220} },
119 { SPOOLSS_FORM_BUILTIN
, "Ledger", {0x696b8,0x44368}, {0x0,0x0,0x696b8,0x44368} },
120 { SPOOLSS_FORM_BUILTIN
, "Legal Extra", {0x3ae94,0x5d048}, {0x0,0x0,0x3ae94,0x5d048} },
121 { SPOOLSS_FORM_BUILTIN
, "Legal", {0x34b5c,0x56d10}, {0x0,0x0,0x34b5c,0x56d10} },
122 { SPOOLSS_FORM_BUILTIN
, "Letter Extra Transverse", {0x3ae94,0x4a6a0}, {0x0,0x0,0x3ae94,0x4a6a0} },
123 { SPOOLSS_FORM_BUILTIN
, "Letter Extra", {0x3ae94,0x4a6a0}, {0x0,0x0,0x3ae94,0x4a6a0} },
124 { SPOOLSS_FORM_BUILTIN
, "Letter Plus", {0x34b5c,0x4eb16}, {0x0,0x0,0x34b5c,0x4eb16} },
125 { SPOOLSS_FORM_BUILTIN
, "Letter Rotated", {0x44368,0x34b5c}, {0x0,0x0,0x44368,0x34b5c} },
126 { SPOOLSS_FORM_BUILTIN
, "Letter Small", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
127 { SPOOLSS_FORM_BUILTIN
, "Letter Transverse", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
128 { SPOOLSS_FORM_BUILTIN
, "Letter", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
129 { SPOOLSS_FORM_BUILTIN
, "Note", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
130 { SPOOLSS_FORM_BUILTIN
, "PRC 16K Rotated", {0x3f7a0,0x2de60}, {0x0,0x0,0x3f7a0,0x2de60} },
131 { SPOOLSS_FORM_BUILTIN
, "PRC 16K", {0x2de60,0x3f7a0}, {0x0,0x0,0x2de60,0x3f7a0} },
132 { SPOOLSS_FORM_BUILTIN
, "PRC 32K Rotated", {0x2cec0,0x1fbd0}, {0x0,0x0,0x2cec0,0x1fbd0} },
133 { SPOOLSS_FORM_BUILTIN
, "PRC 32K", {0x1fbd0,0x2cec0}, {0x0,0x0,0x1fbd0,0x2cec0} },
134 { SPOOLSS_FORM_BUILTIN
, "PRC 32K(Big) Rotated", {0x318f8,0x222e0}, {0x0,0x0,0x318f8,0x222e0} },
135 { SPOOLSS_FORM_BUILTIN
, "PRC 32K(Big)", {0x222e0,0x318f8}, {0x0,0x0,0x222e0,0x318f8} },
136 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #1 Rotated", {0x28488,0x18e70}, {0x0,0x0,0x28488,0x18e70} },
137 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #1", {0x18e70,0x28488}, {0x0,0x0,0x18e70,0x28488} },
138 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #10 Rotated", {0x6fd10,0x4f1a0}, {0x0,0x0,0x6fd10,0x4f1a0} },
139 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #10", {0x4f1a0,0x6fd10}, {0x0,0x0,0x4f1a0,0x6fd10} },
140 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #2 Rotated", {0x2af80,0x18e70}, {0x0,0x0,0x2af80,0x18e70} },
141 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #2", {0x18e70,0x2af80}, {0x0,0x0,0x18e70,0x2af80} },
142 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #3 Rotated", {0x2af80,0x1e848}, {0x0,0x0,0x2af80,0x1e848} },
143 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #3", {0x1e848,0x2af80}, {0x0,0x0,0x1e848,0x2af80} },
144 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #4 Rotated", {0x32c80,0x1adb0}, {0x0,0x0,0x32c80,0x1adb0} },
145 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #4", {0x1adb0,0x32c80}, {0x0,0x0,0x1adb0,0x32c80} },
146 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #5 Rotated", {0x35b60,0x1adb0}, {0x0,0x0,0x35b60,0x1adb0} },
147 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #5", {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} },
148 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #6 Rotated", {0x38270,0x1d4c0}, {0x0,0x0,0x38270,0x1d4c0} },
149 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #6", {0x1d4c0,0x38270}, {0x0,0x0,0x1d4c0,0x38270} },
150 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #7 Rotated", {0x38270,0x27100}, {0x0,0x0,0x38270,0x27100} },
151 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #7", {0x27100,0x38270}, {0x0,0x0,0x27100,0x38270} },
152 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #8 Rotated", {0x4b708,0x1d4c0}, {0x0,0x0,0x4b708,0x1d4c0} },
153 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #8", {0x1d4c0,0x4b708}, {0x0,0x0,0x1d4c0,0x4b708} },
154 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #9 Rotated", {0x4f1a0,0x37e88}, {0x0,0x0,0x4f1a0,0x37e88} },
155 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #9", {0x37e88,0x4f1a0}, {0x0,0x0,0x37e88,0x4f1a0} },
156 { SPOOLSS_FORM_BUILTIN
, "Quarto", {0x347d8,0x43238}, {0x0,0x0,0x347d8,0x43238} },
157 { SPOOLSS_FORM_BUILTIN
, "Reserved48", {0x1,0x1}, {0x0,0x0,0x1,0x1} },
158 { SPOOLSS_FORM_BUILTIN
, "Reserved49", {0x1,0x1}, {0x0,0x0,0x1,0x1} },
159 { SPOOLSS_FORM_BUILTIN
, "Statement", {0x221b4,0x34b5c}, {0x0,0x0,0x221b4,0x34b5c} },
160 { SPOOLSS_FORM_BUILTIN
, "Super A", {0x376b8,0x56ea0}, {0x0,0x0,0x376b8,0x56ea0} },
161 { SPOOLSS_FORM_BUILTIN
, "Super B", {0x4a768,0x76e58}, {0x0,0x0,0x4a768,0x76e58} },
162 { SPOOLSS_FORM_BUILTIN
, "Tabloid Extra", {0x4a6a0,0x6f9f0}, {0x0,0x0,0x4a6a0,0x6f9f0} },
163 { SPOOLSS_FORM_BUILTIN
, "Tabloid", {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} },
164 { SPOOLSS_FORM_BUILTIN
, "US Std Fanfold", {0x5c3e1,0x44368}, {0x0,0x0,0x5c3e1,0x44368} }
167 /********************************************************************
168 static helper functions
169 ********************************************************************/
171 /****************************************************************************
172 Update the changeid time.
173 ****************************************************************************/
177 * @brief Update the ChangeID time of a printer.
179 * This is SO NASTY as some drivers need this to change, others need it
180 * static. This value will change every second, and I must hope that this
181 * is enough..... DON'T CHANGE THIS CODE WITHOUT A TEST MATRIX THE SIZE OF
184 * @return The ChangeID.
186 static uint32_t winreg_printer_rev_changeid(void)
190 get_process_uptime(&tv
);
193 /* Return changeid as msec since spooler restart */
194 return tv
.tv_sec
* 1000 + tv
.tv_usec
/ 1000;
197 * This setting seems to work well but is too untested
198 * to replace the above calculation. Left in for experiementation
199 * of the reader --jerry (Tue Mar 12 09:15:05 CST 2002)
201 return tv
.tv_sec
* 10 + tv
.tv_usec
/ 100000;
208 * @brief Connect to the interal winreg server and open the given printer key.
210 * The function will create the needed subkeys if they don't exist.
212 * @param[in] mem_ctx The memory context to use.
214 * @param[in] server_info The supplied server info.
216 * @param[out] winreg_pipe A pointer for the winreg rpc client pipe.
218 * @param[in] path The path to the key to open.
220 * @param[in] key The key to open.
222 * @param[in] create_key Set to true if the key should be created if it
225 * @param[in] access_mask The access mask to open the key.
227 * @param[out] hive_handle A policy handle for the opened hive.
229 * @param[out] key_handle A policy handle for the opened key.
231 * @return WERR_OK on success, the corresponding DOS error
232 * code if something gone wrong.
234 static WERROR
winreg_printer_openkey(TALLOC_CTX
*mem_ctx
,
235 struct auth_serversupplied_info
*server_info
,
236 struct rpc_pipe_client
**winreg_pipe
,
240 uint32_t access_mask
,
241 struct policy_handle
*hive_handle
,
242 struct policy_handle
*key_handle
)
244 struct rpc_pipe_client
*pipe_handle
;
245 struct winreg_String wkey
, wkeyclass
;
248 WERROR result
= WERR_OK
;
250 /* create winreg connection */
251 status
= rpc_pipe_open_internal(mem_ctx
,
252 &ndr_table_winreg
.syntax_id
,
255 if (!NT_STATUS_IS_OK(status
)) {
256 DEBUG(0, ("winreg_printer_openkey: Could not connect to winreg_pipe: %s\n",
258 return ntstatus_to_werror(status
);
261 status
= rpccli_winreg_OpenHKLM(pipe_handle
,
267 if (!NT_STATUS_IS_OK(status
)) {
268 DEBUG(0, ("winreg_printer_openkey: Could not open HKLM hive: %s\n",
270 talloc_free(pipe_handle
);
271 if (!W_ERROR_IS_OK(result
)) {
274 return ntstatus_to_werror(status
);
278 keyname
= talloc_asprintf(mem_ctx
, "%s\\%s", path
, key
);
280 keyname
= talloc_strdup(mem_ctx
, path
);
282 if (keyname
== NULL
) {
283 talloc_free(pipe_handle
);
291 enum winreg_CreateAction action
= REG_ACTION_NONE
;
293 ZERO_STRUCT(wkeyclass
);
296 status
= rpccli_winreg_CreateKey(pipe_handle
,
308 case REG_ACTION_NONE
:
309 DEBUG(8, ("winreg_printer_openkey:createkey did nothing -- huh?\n"));
311 case REG_CREATED_NEW_KEY
:
312 DEBUG(8, ("winreg_printer_openkey: createkey created %s\n", keyname
));
314 case REG_OPENED_EXISTING_KEY
:
315 DEBUG(8, ("winreg_printer_openkey: createkey opened existing %s\n", keyname
));
319 status
= rpccli_winreg_OpenKey(pipe_handle
,
328 if (!NT_STATUS_IS_OK(status
)) {
329 talloc_free(pipe_handle
);
330 if (!W_ERROR_IS_OK(result
)) {
333 return ntstatus_to_werror(status
);
336 *winreg_pipe
= pipe_handle
;
342 * @brief Create the registry keyname for the given printer.
344 * @param[in] mem_ctx The memory context to use.
346 * @param[in] printer The name of the printer to get the registry key.
348 * @return The registry key or NULL on error.
350 static char *winreg_printer_data_keyname(TALLOC_CTX
*mem_ctx
, const char *printer
) {
351 return talloc_asprintf(mem_ctx
, "%s\\%s", TOP_LEVEL_PRINT_PRINTERS_KEY
, printer
);
357 * @brief Enumerate values of an opened key handle and retrieve the data.
359 * @param[in] mem_ctx The memory context to use.
361 * @param[in] pipe_handle The pipe handle for the rpc connection.
363 * @param[in] key_hnd The opened key handle.
365 * @param[out] pnum_values A pointer to store he number of values found.
367 * @param[out] pnum_values A pointer to store the number of values we found.
369 * @return WERR_OK on success, the corresponding DOS error
370 * code if something gone wrong.
372 static WERROR
winreg_printer_enumvalues(TALLOC_CTX
*mem_ctx
,
373 struct rpc_pipe_client
*pipe_handle
,
374 struct policy_handle
*key_hnd
,
375 uint32_t *pnum_values
,
376 struct spoolss_PrinterEnumValues
**penum_values
)
379 uint32_t num_subkeys
, max_subkeylen
, max_classlen
;
380 uint32_t num_values
, max_valnamelen
, max_valbufsize
;
381 uint32_t secdescsize
;
383 NTTIME last_changed_time
;
384 struct winreg_String classname
;
386 struct spoolss_PrinterEnumValues
*enum_values
;
388 WERROR result
= WERR_OK
;
391 tmp_ctx
= talloc_new(mem_ctx
);
392 if (tmp_ctx
== NULL
) {
396 ZERO_STRUCT(classname
);
398 status
= rpccli_winreg_QueryInfoKey(pipe_handle
,
411 if (!NT_STATUS_IS_OK(status
)) {
412 DEBUG(0, ("winreg_printer_enumvalues: Could not query info: %s\n",
414 if (!W_ERROR_IS_OK(result
)) {
417 result
= ntstatus_to_werror(status
);
421 if (num_values
== 0) {
423 TALLOC_FREE(tmp_ctx
);
427 enum_values
= TALLOC_ARRAY(tmp_ctx
, struct spoolss_PrinterEnumValues
, num_values
);
428 if (enum_values
== NULL
) {
433 for (i
= 0; i
< num_values
; i
++) {
434 struct spoolss_PrinterEnumValues val
;
435 struct winreg_ValNameBuf name_buf
;
436 enum winreg_Type type
= REG_NONE
;
437 uint8_t *data
= NULL
;
443 name_buf
.size
= max_valnamelen
+ 2;
446 data_size
= max_valbufsize
;
447 data
= (uint8_t *) TALLOC(tmp_ctx
, data_size
);
450 status
= rpccli_winreg_EnumValue(pipe_handle
,
460 if (W_ERROR_EQUAL(result
, WERR_NO_MORE_ITEMS
) ) {
462 status
= NT_STATUS_OK
;
466 if (!NT_STATUS_IS_OK(status
)) {
467 DEBUG(0, ("winreg_printer_enumvalues: Could not enumerate values: %s\n",
469 if (!W_ERROR_IS_OK(result
)) {
472 result
= ntstatus_to_werror(status
);
476 if (name_buf
.name
== NULL
) {
477 result
= WERR_INVALID_PARAMETER
;
481 val
.value_name
= talloc_strdup(enum_values
, name_buf
.name
);
482 if (val
.value_name
== NULL
) {
486 val
.value_name_len
= strlen_m_term(val
.value_name
) * 2;
489 val
.data_length
= data_size
;
491 if (val
.data_length
) {
492 val
.data
= talloc(enum_values
, DATA_BLOB
);
493 if (val
.data
== NULL
) {
497 *val
.data
= data_blob_talloc(enum_values
, data
, data_size
);
500 enum_values
[i
] = val
;
503 *pnum_values
= num_values
;
505 *penum_values
= talloc_move(mem_ctx
, &enum_values
);
511 TALLOC_FREE(tmp_ctx
);
518 * @brief Enumerate subkeys of an opened key handle and get the names.
520 * @param[in] mem_ctx The memory context to use.
522 * @param[in] pipe_handle The pipe handle for the rpc connection.
524 * @param[in] key_hnd The opened key handle.
526 * @param[in] pnum_subkeys A pointer to store the number of found subkeys.
528 * @param[in] psubkeys A pointer to an array to store the found names of
531 * @return WERR_OK on success, the corresponding DOS error
532 * code if something gone wrong.
534 static WERROR
winreg_printer_enumkeys(TALLOC_CTX
*mem_ctx
,
535 struct rpc_pipe_client
*pipe_handle
,
536 struct policy_handle
*key_hnd
,
537 uint32_t *pnum_subkeys
,
538 const char ***psubkeys
)
541 const char **subkeys
;
542 uint32_t num_subkeys
, max_subkeylen
, max_classlen
;
543 uint32_t num_values
, max_valnamelen
, max_valbufsize
;
545 NTTIME last_changed_time
;
546 uint32_t secdescsize
;
547 struct winreg_String classname
;
548 WERROR result
= WERR_OK
;
551 tmp_ctx
= talloc_new(mem_ctx
);
552 if (tmp_ctx
== NULL
) {
556 ZERO_STRUCT(classname
);
558 status
= rpccli_winreg_QueryInfoKey(pipe_handle
,
571 if (!NT_STATUS_IS_OK(status
)) {
572 DEBUG(0, ("winreg_printer_enumkeys: Could not query info: %s\n",
574 if (!W_ERROR_IS_OK(result
)) {
577 result
= ntstatus_to_werror(status
);
581 subkeys
= talloc_zero_array(tmp_ctx
, const char *, num_subkeys
+ 2);
582 if (subkeys
== NULL
) {
587 if (num_subkeys
== 0) {
588 subkeys
[0] = talloc_strdup(subkeys
, "");
589 if (subkeys
[0] == NULL
) {
595 *psubkeys
= talloc_move(mem_ctx
, &subkeys
);
598 TALLOC_FREE(tmp_ctx
);
602 for (i
= 0; i
< num_subkeys
; i
++) {
606 struct winreg_StringBuf class_buf
;
607 struct winreg_StringBuf name_buf
;
611 class_buf
.size
= max_classlen
+ 2;
612 class_buf
.length
= 0;
615 name_buf
.size
= max_subkeylen
+ 2;
618 ZERO_STRUCT(modtime
);
620 status
= rpccli_winreg_EnumKey(pipe_handle
,
628 if (W_ERROR_EQUAL(result
, WERR_NO_MORE_ITEMS
) ) {
630 status
= NT_STATUS_OK
;
634 if (!NT_STATUS_IS_OK(status
)) {
635 DEBUG(0, ("winreg_printer_enumkeys: Could not enumerate keys: %s\n",
637 if (!W_ERROR_IS_OK(result
)) {
640 result
= ntstatus_to_werror(status
);
644 if (name_buf
.name
== NULL
) {
645 result
= WERR_INVALID_PARAMETER
;
649 name
= talloc_strdup(subkeys
, name_buf
.name
);
658 *pnum_subkeys
= num_subkeys
;
660 *psubkeys
= talloc_move(mem_ctx
, &subkeys
);
664 TALLOC_FREE(tmp_ctx
);
671 * @brief A function to delete a key and its subkeys recurively.
673 * @param[in] mem_ctx The memory context to use.
675 * @param[in] pipe_handle The pipe handle for the rpc connection.
677 * @param[in] hive_handle A opened hive handle to the key.
679 * @param[in] access_mask The access mask to access the key.
681 * @param[in] key The key to delete
683 * @return WERR_OK on success, the corresponding DOS error
684 * code if something gone wrong.
686 static WERROR
winreg_printer_delete_subkeys(TALLOC_CTX
*mem_ctx
,
687 struct rpc_pipe_client
*pipe_handle
,
688 struct policy_handle
*hive_handle
,
689 uint32_t access_mask
,
692 const char **subkeys
= NULL
;
693 uint32_t num_subkeys
= 0;
694 struct policy_handle key_hnd
;
695 struct winreg_String wkey
;
696 WERROR result
= WERR_OK
;
700 ZERO_STRUCT(key_hnd
);
703 DEBUG(2, ("winreg_printer_delete_subkeys: delete key %s\n", key
));
705 status
= rpccli_winreg_OpenKey(pipe_handle
,
713 if (!NT_STATUS_IS_OK(status
)) {
714 DEBUG(0, ("winreg_printer_delete_subkeys: Could not open key %s: %s\n",
715 wkey
.name
, nt_errstr(status
)));
716 if (!W_ERROR_IS_OK(result
)) {
719 return ntstatus_to_werror(status
);
722 result
= winreg_printer_enumkeys(mem_ctx
,
727 if (!W_ERROR_IS_OK(result
)) {
731 for (i
= 0; i
< num_subkeys
; i
++) {
732 /* create key + subkey */
733 char *subkey
= talloc_asprintf(mem_ctx
, "%s\\%s", key
, subkeys
[i
]);
734 if (subkey
== NULL
) {
738 DEBUG(2, ("winreg_printer_delete_subkeys: delete subkey %s\n", subkey
));
739 result
= winreg_printer_delete_subkeys(mem_ctx
,
744 if (!W_ERROR_IS_OK(result
)) {
749 if (is_valid_policy_hnd(&key_hnd
)) {
750 rpccli_winreg_CloseKey(pipe_handle
, mem_ctx
, &key_hnd
, NULL
);
755 status
= rpccli_winreg_DeleteKey(pipe_handle
,
762 if (is_valid_policy_hnd(&key_hnd
)) {
763 rpccli_winreg_CloseKey(pipe_handle
, mem_ctx
, &key_hnd
, NULL
);
769 static WERROR
winreg_printer_write_sz(TALLOC_CTX
*mem_ctx
,
770 struct rpc_pipe_client
*pipe_handle
,
771 struct policy_handle
*key_handle
,
775 struct winreg_String wvalue
;
777 WERROR result
= WERR_OK
;
782 blob
= data_blob_string_const("");
784 if (!push_reg_sz(mem_ctx
, &blob
, data
)) {
785 DEBUG(0, ("winreg_printer_write_sz: Could not marshall string %s for %s\n",
790 status
= rpccli_winreg_SetValue(pipe_handle
,
798 if (!NT_STATUS_IS_OK(status
)) {
799 DEBUG(0, ("winreg_printer_write_sz: Could not set value %s: %s\n",
800 wvalue
.name
, win_errstr(result
)));
801 if (!W_ERROR_IS_OK(result
)) {
802 result
= ntstatus_to_werror(status
);
809 static WERROR
winreg_printer_write_dword(TALLOC_CTX
*mem_ctx
,
810 struct rpc_pipe_client
*pipe_handle
,
811 struct policy_handle
*key_handle
,
815 struct winreg_String wvalue
;
817 WERROR result
= WERR_OK
;
821 blob
= data_blob_talloc(mem_ctx
, NULL
, 4);
822 SIVAL(blob
.data
, 0, data
);
824 status
= rpccli_winreg_SetValue(pipe_handle
,
832 if (!NT_STATUS_IS_OK(status
)) {
833 DEBUG(0, ("winreg_printer_write_dword: Could not set value %s: %s\n",
834 wvalue
.name
, win_errstr(result
)));
835 if (!W_ERROR_IS_OK(result
)) {
836 result
= ntstatus_to_werror(status
);
843 static WERROR
winreg_printer_write_binary(TALLOC_CTX
*mem_ctx
,
844 struct rpc_pipe_client
*pipe_handle
,
845 struct policy_handle
*key_handle
,
849 struct winreg_String wvalue
;
850 WERROR result
= WERR_OK
;
854 status
= rpccli_winreg_SetValue(pipe_handle
,
862 if (!NT_STATUS_IS_OK(status
)) {
863 DEBUG(0, ("winreg_printer_write_binary: Could not set value %s: %s\n",
864 wvalue
.name
, win_errstr(result
)));
865 if (!W_ERROR_IS_OK(result
)) {
866 result
= ntstatus_to_werror(status
);
873 static WERROR
winreg_printer_query_binary(TALLOC_CTX
*mem_ctx
,
874 struct rpc_pipe_client
*pipe_handle
,
875 struct policy_handle
*key_handle
,
879 struct winreg_String wvalue
;
880 enum winreg_Type type
;
881 WERROR result
= WERR_OK
;
882 uint32_t value_len
= 0;
883 uint32_t data_size
= 0;
888 status
= rpccli_winreg_QueryValue(pipe_handle
,
897 if (!NT_STATUS_IS_OK(status
)) {
898 DEBUG(0, ("winreg_printer_query_dword: Could not query value %s: %s\n",
899 wvalue
.name
, nt_errstr(status
)));
900 if (!W_ERROR_IS_OK(result
)) {
903 result
= ntstatus_to_werror(status
);
907 if (type
!= REG_BINARY
) {
908 result
= WERR_INVALID_DATATYPE
;
911 blob
= data_blob_talloc(mem_ctx
, NULL
, data_size
);
912 if (blob
.data
== NULL
) {
918 status
= rpccli_winreg_QueryValue(pipe_handle
,
927 if (!NT_STATUS_IS_OK(status
)) {
928 DEBUG(0, ("winreg_printer_query_dword: Could not query value %s: %s\n",
929 wvalue
.name
, nt_errstr(status
)));
930 if (!W_ERROR_IS_OK(result
)) {
931 result
= ntstatus_to_werror(status
);
937 data
->data
= blob
.data
;
938 data
->length
= blob
.length
;
944 static WERROR
winreg_printer_query_dword(TALLOC_CTX
*mem_ctx
,
945 struct rpc_pipe_client
*pipe_handle
,
946 struct policy_handle
*key_handle
,
950 struct winreg_String wvalue
;
951 enum winreg_Type type
;
952 WERROR result
= WERR_OK
;
953 uint32_t value_len
= 0;
954 uint32_t data_size
= 0;
959 status
= rpccli_winreg_QueryValue(pipe_handle
,
968 if (!NT_STATUS_IS_OK(status
)) {
969 DEBUG(0, ("winreg_printer_query_dword: Could not query value %s: %s\n",
970 wvalue
.name
, nt_errstr(status
)));
971 if (!W_ERROR_IS_OK(result
)) {
974 result
= ntstatus_to_werror(status
);
978 if (type
!= REG_DWORD
) {
979 result
= WERR_INVALID_DATATYPE
;
983 if (data_size
!= 4) {
984 result
= WERR_INVALID_DATA
;
988 blob
= data_blob_talloc(mem_ctx
, NULL
, data_size
);
989 if (blob
.data
== NULL
) {
995 status
= rpccli_winreg_QueryValue(pipe_handle
,
1004 if (!NT_STATUS_IS_OK(status
)) {
1005 DEBUG(0, ("winreg_printer_query_dword: Could not query value %s: %s\n",
1006 wvalue
.name
, nt_errstr(status
)));
1007 if (!W_ERROR_IS_OK(result
)) {
1008 result
= ntstatus_to_werror(status
);
1014 *data
= IVAL(blob
.data
, 0);
1020 static WERROR
winreg_printer_write_multi_sz(TALLOC_CTX
*mem_ctx
,
1021 struct rpc_pipe_client
*pipe_handle
,
1022 struct policy_handle
*key_handle
,
1026 struct winreg_String wvalue
;
1028 WERROR result
= WERR_OK
;
1031 wvalue
.name
= value
;
1032 if (!push_reg_multi_sz(mem_ctx
, &blob
, data
)) {
1035 status
= rpccli_winreg_SetValue(pipe_handle
,
1043 if (!NT_STATUS_IS_OK(status
)) {
1044 DEBUG(0, ("winreg_printer_write_multi_sz: Could not set value %s: %s\n",
1045 wvalue
.name
, win_errstr(result
)));
1046 if (!W_ERROR_IS_OK(result
)) {
1047 result
= ntstatus_to_werror(status
);
1054 static WERROR
winreg_printer_opendriver(TALLOC_CTX
*mem_ctx
,
1055 struct auth_serversupplied_info
*server_info
,
1056 const char *drivername
,
1057 const char *architecture
,
1059 uint32_t access_mask
,
1061 struct rpc_pipe_client
**winreg_pipe
,
1062 struct policy_handle
*hive_hnd
,
1063 struct policy_handle
*key_hnd
)
1068 key_name
= talloc_asprintf(mem_ctx
, "%s\\Environments\\%s\\Drivers\\Version-%u",
1069 TOP_LEVEL_CONTROL_KEY
,
1070 architecture
, version
);
1075 result
= winreg_printer_openkey(mem_ctx
,
1087 static WERROR
winreg_enumval_to_dword(TALLOC_CTX
*mem_ctx
,
1088 struct spoolss_PrinterEnumValues
*v
,
1089 const char *valuename
, uint32_t *dw
)
1091 /* just return if it is not the one we are looking for */
1092 if (strcmp(valuename
, v
->value_name
) != 0) {
1093 return WERR_NOT_FOUND
;
1096 if (v
->type
!= REG_DWORD
) {
1097 return WERR_INVALID_DATATYPE
;
1100 *dw
= IVAL(v
->data
->data
, 0);
1104 static WERROR
winreg_enumval_to_sz(TALLOC_CTX
*mem_ctx
,
1105 struct spoolss_PrinterEnumValues
*v
,
1106 const char *valuename
, const char **_str
)
1108 /* just return if it is not the one we are looking for */
1109 if (strcmp(valuename
, v
->value_name
) != 0) {
1110 return WERR_NOT_FOUND
;
1113 if (v
->type
!= REG_SZ
) {
1114 return WERR_INVALID_DATATYPE
;
1117 if (!pull_reg_sz(mem_ctx
, v
->data
, _str
)) {
1124 static WERROR
winreg_enumval_to_multi_sz(TALLOC_CTX
*mem_ctx
,
1125 struct spoolss_PrinterEnumValues
*v
,
1126 const char *valuename
,
1127 const char ***array
)
1129 /* just return if it is not the one we are looking for */
1130 if (strcmp(valuename
, v
->value_name
) != 0) {
1131 return WERR_NOT_FOUND
;
1134 if (v
->type
!= REG_MULTI_SZ
) {
1135 return WERR_INVALID_DATATYPE
;
1138 if (!pull_reg_multi_sz(mem_ctx
, v
->data
, array
)) {
1145 static WERROR
winreg_printer_write_date(TALLOC_CTX
*mem_ctx
,
1146 struct rpc_pipe_client
*pipe_handle
,
1147 struct policy_handle
*key_handle
,
1151 struct winreg_String wvalue
;
1153 WERROR result
= WERR_OK
;
1159 t
= nt_time_to_unix(data
);
1161 str
= talloc_asprintf(mem_ctx
, "%02d/%02d/%04d",
1162 tm
->tm_mon
+ 1, tm
->tm_mday
, tm
->tm_year
+ 1900);
1167 wvalue
.name
= value
;
1168 if (!push_reg_sz(mem_ctx
, &blob
, str
)) {
1171 status
= rpccli_winreg_SetValue(pipe_handle
,
1179 if (!NT_STATUS_IS_OK(status
)) {
1180 DEBUG(0, ("winreg_printer_write_date: Could not set value %s: %s\n",
1181 wvalue
.name
, win_errstr(result
)));
1182 if (!W_ERROR_IS_OK(result
)) {
1183 result
= ntstatus_to_werror(status
);
1190 static WERROR
winreg_printer_date_to_NTTIME(const char *str
, NTTIME
*data
)
1197 if (sscanf(str
, "%d/%d/%d",
1198 &tm
.tm_mon
, &tm
.tm_mday
, &tm
.tm_year
) != 3) {
1199 return WERR_INVALID_PARAMETER
;
1206 unix_to_nt_time(data
, t
);
1211 static WERROR
winreg_printer_write_ver(TALLOC_CTX
*mem_ctx
,
1212 struct rpc_pipe_client
*pipe_handle
,
1213 struct policy_handle
*key_handle
,
1217 struct winreg_String wvalue
;
1219 WERROR result
= WERR_OK
;
1223 /* FIXME: check format is right,
1224 * this needs to be something like: 6.1.7600.16385 */
1225 str
= talloc_asprintf(mem_ctx
, "%u.%u.%u.%u",
1226 (unsigned)((data
>> 48) & 0xFFFF),
1227 (unsigned)((data
>> 32) & 0xFFFF),
1228 (unsigned)((data
>> 16) & 0xFFFF),
1229 (unsigned)(data
& 0xFFFF));
1234 wvalue
.name
= value
;
1235 if (!push_reg_sz(mem_ctx
, &blob
, str
)) {
1238 status
= rpccli_winreg_SetValue(pipe_handle
,
1246 if (!NT_STATUS_IS_OK(status
)) {
1247 DEBUG(0, ("winreg_printer_write_date: Could not set value %s: %s\n",
1248 wvalue
.name
, win_errstr(result
)));
1249 if (!W_ERROR_IS_OK(result
)) {
1250 result
= ntstatus_to_werror(status
);
1257 static WERROR
winreg_printer_ver_to_dword(const char *str
, uint64_t *data
)
1259 unsigned int v1
, v2
, v3
, v4
;
1261 if (sscanf(str
, "%u.%u.%u.%u", &v1
, &v2
, &v3
, &v4
) != 4) {
1262 return WERR_INVALID_PARAMETER
;
1265 *data
= ((uint64_t)(v1
& 0xFFFF) << 48) +
1266 ((uint64_t)(v2
& 0xFFFF) << 32) +
1267 ((uint64_t)(v3
& 0xFFFF) << 16) +
1268 (uint64_t)(v2
& 0xFFFF);
1273 /********************************************************************
1274 Public winreg function for spoolss
1275 ********************************************************************/
1277 WERROR
winreg_create_printer(TALLOC_CTX
*mem_ctx
,
1278 struct auth_serversupplied_info
*server_info
,
1279 const char *servername
,
1280 const char *sharename
)
1282 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1283 struct rpc_pipe_client
*winreg_pipe
= NULL
;
1284 struct policy_handle hive_hnd
, key_hnd
;
1285 struct spoolss_SetPrinterInfo2
*info2
;
1286 struct security_descriptor
*secdesc
;
1287 struct winreg_String wkey
, wkeyclass
;
1289 const char *subkeys
[] = { SPOOL_DSDRIVER_KEY
, SPOOL_DSSPOOLER_KEY
, SPOOL_PRINTERDATA_KEY
};
1290 uint32_t i
, count
= ARRAY_SIZE(subkeys
);
1291 uint32_t info2_mask
= 0;
1292 WERROR result
= WERR_OK
;
1293 TALLOC_CTX
*tmp_ctx
;
1295 tmp_ctx
= talloc_new(mem_ctx
);
1296 if (tmp_ctx
== NULL
) {
1300 path
= winreg_printer_data_keyname(tmp_ctx
, sharename
);
1302 TALLOC_FREE(tmp_ctx
);
1306 ZERO_STRUCT(hive_hnd
);
1307 ZERO_STRUCT(key_hnd
);
1309 result
= winreg_printer_openkey(tmp_ctx
,
1318 if (W_ERROR_IS_OK(result
)) {
1319 DEBUG(2, ("winreg_create_printer: Skipping, %s already exists\n", path
));
1321 } else if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
1322 DEBUG(2, ("winreg_create_printer: Creating default values in %s\n", path
));
1323 } else if (!W_ERROR_IS_OK(result
)) {
1324 DEBUG(0, ("winreg_create_printer: Could not open key %s: %s\n",
1325 path
, win_errstr(result
)));
1329 /* Create the main key */
1330 result
= winreg_printer_openkey(tmp_ctx
,
1339 if (!W_ERROR_IS_OK(result
)) {
1340 DEBUG(0, ("winreg_create_printer_keys: Could not create key %s: %s\n",
1341 path
, win_errstr(result
)));
1345 if (is_valid_policy_hnd(&key_hnd
)) {
1346 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
1349 /* Create subkeys */
1350 for (i
= 0; i
< count
; i
++) {
1352 enum winreg_CreateAction action
= REG_ACTION_NONE
;
1354 ZERO_STRUCT(key_hnd
);
1357 wkey
.name
= talloc_asprintf(tmp_ctx
, "%s\\%s", path
, subkeys
[i
]);
1358 if (wkey
.name
== NULL
) {
1359 result
= WERR_NOMEM
;
1363 ZERO_STRUCT(wkeyclass
);
1364 wkeyclass
.name
= "";
1366 status
= rpccli_winreg_CreateKey(winreg_pipe
,
1377 if (!NT_STATUS_IS_OK(status
)) {
1378 DEBUG(0, ("winreg_create_printer_keys: Could not create key %s: %s\n",
1379 wkey
.name
, win_errstr(result
)));
1380 if (!W_ERROR_IS_OK(result
)) {
1381 result
= ntstatus_to_werror(status
);
1388 const char *dnssuffix
;
1389 const char *longname
;
1390 const char *uncname
;
1392 result
= winreg_printer_write_sz(tmp_ctx
,
1395 SPOOL_REG_PRINTERNAME
,
1397 if (!W_ERROR_IS_OK(result
)) {
1401 result
= winreg_printer_write_sz(tmp_ctx
,
1404 SPOOL_REG_SHORTSERVERNAME
,
1406 if (!W_ERROR_IS_OK(result
)) {
1410 /* We make the assumption that the netbios name
1411 * is the same as the DNS name since the former
1412 * will be what we used to join the domain
1414 dnssuffix
= get_mydnsdomname(tmp_ctx
);
1415 if (dnssuffix
!= NULL
&& dnssuffix
[0] != '\0') {
1416 longname
= talloc_asprintf(tmp_ctx
, "%s.%s", global_myname(), dnssuffix
);
1418 longname
= talloc_strdup(tmp_ctx
, global_myname());
1420 if (longname
== NULL
) {
1421 result
= WERR_NOMEM
;
1425 result
= winreg_printer_write_sz(tmp_ctx
,
1428 SPOOL_REG_SERVERNAME
,
1430 if (!W_ERROR_IS_OK(result
)) {
1434 uncname
= talloc_asprintf(tmp_ctx
, "\\\\%s\\%s",
1435 longname
, sharename
);
1436 if (uncname
== NULL
) {
1437 result
= WERR_NOMEM
;
1441 result
= winreg_printer_write_sz(tmp_ctx
,
1446 if (!W_ERROR_IS_OK(result
)) {
1450 result
= winreg_printer_write_dword(tmp_ctx
,
1453 SPOOL_REG_VERSIONNUMBER
,
1455 if (!W_ERROR_IS_OK(result
)) {
1459 result
= winreg_printer_write_dword(tmp_ctx
,
1462 SPOOL_REG_PRINTSTARTTIME
,
1464 if (!W_ERROR_IS_OK(result
)) {
1468 result
= winreg_printer_write_dword(tmp_ctx
,
1471 SPOOL_REG_PRINTENDTIME
,
1473 if (!W_ERROR_IS_OK(result
)) {
1477 result
= winreg_printer_write_dword(tmp_ctx
,
1482 if (!W_ERROR_IS_OK(result
)) {
1486 result
= winreg_printer_write_dword(tmp_ctx
,
1489 SPOOL_REG_PRINTKEEPPRINTEDJOBS
,
1491 if (!W_ERROR_IS_OK(result
)) {
1499 if (is_valid_policy_hnd(&key_hnd
)) {
1500 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
1503 info2
= talloc_zero(tmp_ctx
, struct spoolss_SetPrinterInfo2
);
1504 if (info2
== NULL
) {
1505 result
= WERR_NOMEM
;
1509 if (servername
!= NULL
) {
1510 info2
->printername
= talloc_asprintf(tmp_ctx
, "\\\\%s\\%s",
1511 servername
, sharename
);
1513 info2
->printername
= sharename
;
1515 if (info2
->printername
== NULL
) {
1516 result
= WERR_NOMEM
;
1519 info2_mask
|= SPOOLSS_PRINTER_INFO_PRINTERNAME
;
1521 info2
->sharename
= sharename
;
1522 info2_mask
|= SPOOLSS_PRINTER_INFO_SHARENAME
;
1524 info2
->portname
= SAMBA_PRINTER_PORT_NAME
;
1525 info2_mask
|= SPOOLSS_PRINTER_INFO_PORTNAME
;
1527 info2
->printprocessor
= "winprint";
1528 info2_mask
|= SPOOLSS_PRINTER_INFO_PRINTPROCESSOR
;
1530 info2
->datatype
= "RAW";
1531 info2_mask
|= SPOOLSS_PRINTER_INFO_DATATYPE
;
1533 info2
->comment
= "";
1534 info2_mask
|= SPOOLSS_PRINTER_INFO_COMMENT
;
1536 info2
->attributes
= PRINTER_ATTRIBUTE_SAMBA
;
1537 info2_mask
|= SPOOLSS_PRINTER_INFO_ATTRIBUTES
;
1539 info2
->starttime
= 0; /* Minutes since 12:00am GMT */
1540 info2_mask
|= SPOOLSS_PRINTER_INFO_STARTTIME
;
1542 info2
->untiltime
= 0; /* Minutes since 12:00am GMT */
1543 info2_mask
|= SPOOLSS_PRINTER_INFO_UNTILTIME
;
1545 info2
->priority
= 1;
1546 info2_mask
|= SPOOLSS_PRINTER_INFO_PRIORITY
;
1548 info2
->defaultpriority
= 1;
1549 info2_mask
|= SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY
;
1551 result
= spoolss_create_default_secdesc(tmp_ctx
, &secdesc
);
1552 if (!W_ERROR_IS_OK(result
)) {
1555 info2_mask
|= SPOOLSS_PRINTER_INFO_SECDESC
;
1558 * Don't write a default Device Mode to the registry! The Device Mode is
1559 * only written to disk with a SetPrinter level 2 or 8.
1562 result
= winreg_update_printer(tmp_ctx
,
1571 if (winreg_pipe
!= NULL
) {
1572 if (is_valid_policy_hnd(&key_hnd
)) {
1573 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
1575 if (is_valid_policy_hnd(&hive_hnd
)) {
1576 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
1580 talloc_free(tmp_ctx
);
1584 WERROR
winreg_update_printer(TALLOC_CTX
*mem_ctx
,
1585 struct auth_serversupplied_info
*server_info
,
1586 const char *sharename
,
1587 uint32_t info2_mask
,
1588 struct spoolss_SetPrinterInfo2
*info2
,
1589 struct spoolss_DeviceMode
*devmode
,
1590 struct security_descriptor
*secdesc
)
1592 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1593 struct rpc_pipe_client
*winreg_pipe
= NULL
;
1594 struct policy_handle hive_hnd
, key_hnd
;
1595 int snum
= lp_servicenumber(sharename
);
1596 enum ndr_err_code ndr_err
;
1599 WERROR result
= WERR_OK
;
1600 TALLOC_CTX
*tmp_ctx
;
1602 tmp_ctx
= talloc_new(mem_ctx
);
1603 if (tmp_ctx
== NULL
) {
1607 path
= winreg_printer_data_keyname(tmp_ctx
, sharename
);
1609 TALLOC_FREE(tmp_ctx
);
1613 ZERO_STRUCT(hive_hnd
);
1614 ZERO_STRUCT(key_hnd
);
1616 result
= winreg_printer_openkey(tmp_ctx
,
1625 if (!W_ERROR_IS_OK(result
)) {
1626 DEBUG(0, ("winreg_update_printer: Could not open key %s: %s\n",
1627 path
, win_errstr(result
)));
1631 if (info2_mask
& SPOOLSS_PRINTER_INFO_ATTRIBUTES
) {
1632 result
= winreg_printer_write_dword(tmp_ctx
,
1637 if (!W_ERROR_IS_OK(result
)) {
1643 if (info2_mask
& SPOOLSS_PRINTER_INFO_AVERAGEPPM
) {
1644 result
= winreg_printer_write_dword(tmp_ctx
,
1649 if (!W_ERROR_IS_OK(result
)) {
1655 if (info2_mask
& SPOOLSS_PRINTER_INFO_COMMENT
) {
1656 result
= winreg_printer_write_sz(tmp_ctx
,
1661 if (!W_ERROR_IS_OK(result
)) {
1666 if (info2_mask
& SPOOLSS_PRINTER_INFO_DATATYPE
) {
1667 result
= winreg_printer_write_sz(tmp_ctx
,
1672 if (!W_ERROR_IS_OK(result
)) {
1677 if (info2_mask
& SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY
) {
1678 result
= winreg_printer_write_dword(tmp_ctx
,
1682 info2
->defaultpriority
);
1683 if (!W_ERROR_IS_OK(result
)) {
1688 if (info2_mask
& SPOOLSS_PRINTER_INFO_DEVMODE
) {
1690 * Some client drivers freak out if there is a NULL devmode
1691 * (probably the driver is not checking before accessing
1692 * the devmode pointer) --jerry
1694 if (devmode
== NULL
&& lp_default_devmode(snum
) && info2
!= NULL
) {
1695 result
= spoolss_create_default_devmode(tmp_ctx
,
1698 if (!W_ERROR_IS_OK(result
)) {
1702 ndr_err
= ndr_push_struct_blob(&blob
, tmp_ctx
, devmode
,
1703 (ndr_push_flags_fn_t
) ndr_push_spoolss_DeviceMode
);
1704 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1705 DEBUG(0, ("winreg_update_printer: Failed to marshall device mode\n"));
1706 result
= WERR_NOMEM
;
1710 result
= winreg_printer_write_binary(tmp_ctx
,
1715 if (!W_ERROR_IS_OK(result
)) {
1720 if (info2_mask
& SPOOLSS_PRINTER_INFO_DRIVERNAME
) {
1721 result
= winreg_printer_write_sz(tmp_ctx
,
1726 if (!W_ERROR_IS_OK(result
)) {
1731 if (info2_mask
& SPOOLSS_PRINTER_INFO_LOCATION
) {
1732 result
= winreg_printer_write_sz(tmp_ctx
,
1737 if (!W_ERROR_IS_OK(result
)) {
1742 if (info2_mask
& SPOOLSS_PRINTER_INFO_PARAMETERS
) {
1743 result
= winreg_printer_write_sz(tmp_ctx
,
1748 if (!W_ERROR_IS_OK(result
)) {
1753 if (info2_mask
& SPOOLSS_PRINTER_INFO_PORTNAME
) {
1754 result
= winreg_printer_write_sz(tmp_ctx
,
1759 if (!W_ERROR_IS_OK(result
)) {
1764 if (info2_mask
& SPOOLSS_PRINTER_INFO_PRINTERNAME
) {
1766 * in addprinter: no servername and the printer is the name
1767 * in setprinter: servername is \\server
1768 * and printer is \\server\\printer
1770 * Samba manages only local printers.
1771 * we currently don't support things like i
1772 * path=\\other_server\printer
1774 * We only store the printername, not \\server\printername
1776 const char *p
= strrchr(info2
->printername
, '\\');
1778 p
= info2
->printername
;
1782 result
= winreg_printer_write_sz(tmp_ctx
,
1787 if (!W_ERROR_IS_OK(result
)) {
1792 if (info2_mask
& SPOOLSS_PRINTER_INFO_PRINTPROCESSOR
) {
1793 result
= winreg_printer_write_sz(tmp_ctx
,
1797 info2
->printprocessor
);
1798 if (!W_ERROR_IS_OK(result
)) {
1803 if (info2_mask
& SPOOLSS_PRINTER_INFO_PRIORITY
) {
1804 result
= winreg_printer_write_dword(tmp_ctx
,
1809 if (!W_ERROR_IS_OK(result
)) {
1814 if (info2_mask
& SPOOLSS_PRINTER_INFO_SECDESC
) {
1816 * We need a security descriptor, if it isn't specified by
1817 * AddPrinter{Ex} then create a default descriptor.
1819 if (secdesc
== NULL
) {
1820 result
= spoolss_create_default_secdesc(tmp_ctx
, &secdesc
);
1821 if (!W_ERROR_IS_OK(result
)) {
1825 result
= winreg_set_printer_secdesc(tmp_ctx
,
1829 if (!W_ERROR_IS_OK(result
)) {
1834 if (info2_mask
& SPOOLSS_PRINTER_INFO_SEPFILE
) {
1835 result
= winreg_printer_write_sz(tmp_ctx
,
1840 if (!W_ERROR_IS_OK(result
)) {
1845 if (info2_mask
& SPOOLSS_PRINTER_INFO_SHARENAME
) {
1846 result
= winreg_printer_write_sz(tmp_ctx
,
1851 if (!W_ERROR_IS_OK(result
)) {
1856 if (info2_mask
& SPOOLSS_PRINTER_INFO_STARTTIME
) {
1857 result
= winreg_printer_write_dword(tmp_ctx
,
1862 if (!W_ERROR_IS_OK(result
)) {
1867 if (info2_mask
& SPOOLSS_PRINTER_INFO_STATUS
) {
1868 result
= winreg_printer_write_dword(tmp_ctx
,
1873 if (!W_ERROR_IS_OK(result
)) {
1878 if (info2_mask
& SPOOLSS_PRINTER_INFO_UNTILTIME
) {
1879 result
= winreg_printer_write_dword(tmp_ctx
,
1884 if (!W_ERROR_IS_OK(result
)) {
1889 result
= winreg_printer_write_dword(tmp_ctx
,
1893 winreg_printer_rev_changeid());
1894 if (!W_ERROR_IS_OK(result
)) {
1900 if (winreg_pipe
!= NULL
) {
1901 if (is_valid_policy_hnd(&key_hnd
)) {
1902 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
1904 if (is_valid_policy_hnd(&hive_hnd
)) {
1905 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
1909 TALLOC_FREE(tmp_ctx
);
1913 WERROR
winreg_get_printer(TALLOC_CTX
*mem_ctx
,
1914 struct auth_serversupplied_info
*server_info
,
1915 const char *servername
,
1916 const char *printer
,
1917 struct spoolss_PrinterInfo2
**pinfo2
)
1919 struct spoolss_PrinterInfo2
*info2
;
1920 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1921 struct rpc_pipe_client
*winreg_pipe
= NULL
;
1922 struct policy_handle hive_hnd
, key_hnd
;
1923 struct spoolss_PrinterEnumValues
*enum_values
= NULL
;
1924 struct spoolss_PrinterEnumValues
*v
;
1925 enum ndr_err_code ndr_err
;
1927 int snum
= lp_servicenumber(printer
);
1928 uint32_t num_values
= 0;
1931 WERROR result
= WERR_OK
;
1932 TALLOC_CTX
*tmp_ctx
;
1934 tmp_ctx
= talloc_new(mem_ctx
);
1935 if (tmp_ctx
== NULL
) {
1939 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
1941 TALLOC_FREE(tmp_ctx
);
1945 result
= winreg_printer_openkey(tmp_ctx
,
1954 if (!W_ERROR_IS_OK(result
)) {
1955 DEBUG(0, ("winreg_get_printer: Could not open key %s: %s\n",
1956 path
, win_errstr(result
)));
1960 result
= winreg_printer_enumvalues(tmp_ctx
,
1965 if (!W_ERROR_IS_OK(result
)) {
1966 DEBUG(0, ("winreg_get_printer: Could not enumerate values in %s: %s\n",
1967 path
, win_errstr(result
)));
1971 info2
= talloc_zero(tmp_ctx
, struct spoolss_PrinterInfo2
);
1972 if (info2
== NULL
) {
1973 result
= WERR_NOMEM
;
1977 info2
->servername
= EMPTY_STRING
;
1978 info2
->printername
= EMPTY_STRING
;
1979 info2
->sharename
= EMPTY_STRING
;
1980 info2
->portname
= EMPTY_STRING
;
1981 info2
->drivername
= EMPTY_STRING
;
1982 info2
->comment
= EMPTY_STRING
;
1983 info2
->location
= EMPTY_STRING
;
1984 info2
->sepfile
= EMPTY_STRING
;
1985 info2
->printprocessor
= EMPTY_STRING
;
1986 info2
->datatype
= EMPTY_STRING
;
1987 info2
->parameters
= EMPTY_STRING
;
1989 if (servername
!= NULL
&& servername
[0] != '\0') {
1990 info2
->servername
= talloc_asprintf(info2
, "\\\\%s", servername
);
1991 if (info2
->servername
== NULL
) {
1992 result
= WERR_NOMEM
;
1997 for (i
= 0; i
< num_values
; i
++) {
1998 v
= &enum_values
[i
];
2000 result
= winreg_enumval_to_sz(info2
,
2003 &info2
->printername
);
2004 CHECK_ERROR(result
);
2006 result
= winreg_enumval_to_sz(info2
,
2010 CHECK_ERROR(result
);
2012 result
= winreg_enumval_to_sz(info2
,
2016 CHECK_ERROR(result
);
2018 result
= winreg_enumval_to_sz(info2
,
2022 CHECK_ERROR(result
);
2024 result
= winreg_enumval_to_sz(info2
,
2028 CHECK_ERROR(result
);
2030 result
= winreg_enumval_to_sz(info2
,
2034 CHECK_ERROR(result
);
2036 result
= winreg_enumval_to_sz(info2
,
2039 &info2
->printprocessor
);
2040 CHECK_ERROR(result
);
2042 result
= winreg_enumval_to_sz(info2
,
2046 CHECK_ERROR(result
);
2048 result
= winreg_enumval_to_sz(info2
,
2051 &info2
->parameters
);
2052 CHECK_ERROR(result
);
2054 result
= winreg_enumval_to_sz(info2
,
2057 &info2
->drivername
);
2058 CHECK_ERROR(result
);
2060 result
= winreg_enumval_to_dword(info2
,
2063 &info2
->attributes
);
2064 CHECK_ERROR(result
);
2066 result
= winreg_enumval_to_dword(info2
,
2070 CHECK_ERROR(result
);
2072 result
= winreg_enumval_to_dword(info2
,
2075 &info2
->defaultpriority
);
2076 CHECK_ERROR(result
);
2078 result
= winreg_enumval_to_dword(info2
,
2082 CHECK_ERROR(result
);
2084 result
= winreg_enumval_to_dword(info2
,
2088 CHECK_ERROR(result
);
2090 result
= winreg_enumval_to_dword(info2
,
2094 CHECK_ERROR(result
);
2096 result
= winreg_enumval_to_dword(info2
,
2100 CHECK_ERROR(result
);
2103 if (!W_ERROR_IS_OK(result
)) {
2104 DEBUG(0, ("winreg_get_printer: winreg_enumval_to_TYPE() failed "
2107 win_errstr(result
)));
2111 /* Create the printername */
2112 if (info2
->servername
[0] != '\0') {
2113 if (lp_force_printername(snum
)) {
2114 const char *p
= talloc_asprintf(info2
, "%s\\%s",
2118 result
= WERR_NOMEM
;
2121 info2
->printername
= p
;
2123 char *p
= talloc_asprintf(info2
, "%s\\%s",
2125 info2
->printername
);
2127 result
= WERR_NOMEM
;
2130 info2
->printername
= p
;
2134 /* Construct the Device Mode */
2135 result
= winreg_printer_query_binary(tmp_ctx
,
2140 if (W_ERROR_IS_OK(result
)) {
2141 info2
->devmode
= talloc_zero(info2
, struct spoolss_DeviceMode
);
2142 if (info2
->devmode
== NULL
) {
2143 result
= WERR_NOMEM
;
2146 ndr_err
= ndr_pull_struct_blob(&blob
,
2149 (ndr_pull_flags_fn_t
) ndr_pull_spoolss_DeviceMode
);
2150 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
2151 DEBUG(0, ("winreg_get_printer: Failed to unmarshall device mode\n"));
2152 result
= WERR_NOMEM
;
2157 if (info2
->devmode
== NULL
&& lp_default_devmode(snum
)) {
2158 result
= spoolss_create_default_devmode(info2
,
2161 if (!W_ERROR_IS_OK(result
)) {
2166 if (info2
->devmode
!= NULL
) {
2167 info2
->devmode
->devicename
= talloc_strdup(info2
->devmode
,
2168 info2
->printername
);
2169 if (info2
->devmode
->devicename
== NULL
) {
2170 DEBUG(0, ("winreg_get_printer: Failed to set devicename\n"));
2171 result
= WERR_NOMEM
;
2176 result
= winreg_get_printer_secdesc(info2
,
2180 if (!W_ERROR_IS_OK(result
)) {
2184 /* Fix for OS/2 drivers. */
2185 if (get_remote_arch() == RA_OS2
) {
2186 spoolss_map_to_os2_driver(info2
, &info2
->drivername
);
2190 *pinfo2
= talloc_move(mem_ctx
, &info2
);
2195 if (winreg_pipe
!= NULL
) {
2196 if (is_valid_policy_hnd(&key_hnd
)) {
2197 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
2199 if (is_valid_policy_hnd(&hive_hnd
)) {
2200 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
2204 TALLOC_FREE(tmp_ctx
);
2208 WERROR
winreg_get_printer_secdesc(TALLOC_CTX
*mem_ctx
,
2209 struct auth_serversupplied_info
*server_info
,
2210 const char *sharename
,
2211 struct spoolss_security_descriptor
**psecdesc
)
2213 struct spoolss_security_descriptor
*secdesc
;
2214 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2215 struct rpc_pipe_client
*winreg_pipe
= NULL
;
2216 struct policy_handle hive_hnd
, key_hnd
;
2217 enum ndr_err_code ndr_err
;
2220 TALLOC_CTX
*tmp_ctx
;
2223 tmp_ctx
= talloc_new(mem_ctx
);
2224 if (tmp_ctx
== NULL
) {
2228 path
= winreg_printer_data_keyname(tmp_ctx
, sharename
);
2230 talloc_free(tmp_ctx
);
2234 ZERO_STRUCT(hive_hnd
);
2235 ZERO_STRUCT(key_hnd
);
2237 result
= winreg_printer_openkey(tmp_ctx
,
2246 if (!W_ERROR_IS_OK(result
)) {
2247 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
2248 goto create_default
;
2253 result
= winreg_printer_query_binary(tmp_ctx
,
2258 if (!W_ERROR_IS_OK(result
)) {
2259 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
2260 goto create_default
;
2265 secdesc
= talloc_zero(tmp_ctx
, struct spoolss_security_descriptor
);
2266 if (secdesc
== NULL
) {
2267 result
= WERR_NOMEM
;
2270 ndr_err
= ndr_pull_struct_blob(&blob
,
2273 (ndr_pull_flags_fn_t
) ndr_pull_security_descriptor
);
2274 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
2275 DEBUG(0, ("winreg_get_secdesc: Failed to unmarshall security descriptor\n"));
2276 result
= WERR_NOMEM
;
2281 *psecdesc
= talloc_move(mem_ctx
, &secdesc
);
2288 result
= spoolss_create_default_secdesc(tmp_ctx
, &secdesc
);
2289 if (!W_ERROR_IS_OK(result
)) {
2293 /* If security descriptor is owned by S-1-1-0 and winbindd is up,
2294 this security descriptor has been created when winbindd was
2295 down. Take ownership of security descriptor. */
2296 if (sid_equal(secdesc
->owner_sid
, &global_sid_World
)) {
2297 struct dom_sid owner_sid
;
2299 /* Change sd owner to workgroup administrator */
2301 if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid
)) {
2302 struct spoolss_security_descriptor
*new_secdesc
;
2306 sid_append_rid(&owner_sid
, DOMAIN_RID_ADMINISTRATOR
);
2308 new_secdesc
= make_sec_desc(tmp_ctx
,
2317 if (new_secdesc
== NULL
) {
2318 result
= WERR_NOMEM
;
2322 /* Swap with other one */
2323 secdesc
= new_secdesc
;
2327 ndr_err
= ndr_push_struct_blob(&blob
, tmp_ctx
, secdesc
,
2328 (ndr_push_flags_fn_t
) ndr_push_security_descriptor
);
2329 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
2330 DEBUG(0, ("winreg_set_secdesc: Failed to marshall security descriptor\n"));
2331 result
= WERR_NOMEM
;
2335 result
= winreg_printer_write_binary(tmp_ctx
,
2340 if (!W_ERROR_IS_OK(result
)) {
2345 *psecdesc
= talloc_move(mem_ctx
, &secdesc
);
2350 if (winreg_pipe
!= NULL
) {
2351 if (is_valid_policy_hnd(&key_hnd
)) {
2352 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
2354 if (is_valid_policy_hnd(&hive_hnd
)) {
2355 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
2359 talloc_free(tmp_ctx
);
2363 WERROR
winreg_set_printer_secdesc(TALLOC_CTX
*mem_ctx
,
2364 struct auth_serversupplied_info
*server_info
,
2365 const char *sharename
,
2366 const struct spoolss_security_descriptor
*secdesc
)
2368 const struct spoolss_security_descriptor
*new_secdesc
= secdesc
;
2369 struct spoolss_security_descriptor
*old_secdesc
;
2370 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2371 struct rpc_pipe_client
*winreg_pipe
= NULL
;
2372 struct policy_handle hive_hnd
, key_hnd
;
2373 enum ndr_err_code ndr_err
;
2376 TALLOC_CTX
*tmp_ctx
;
2379 tmp_ctx
= talloc_new(mem_ctx
);
2380 if (tmp_ctx
== NULL
) {
2384 path
= winreg_printer_data_keyname(tmp_ctx
, sharename
);
2386 talloc_free(tmp_ctx
);
2391 * The old owner and group sids of the security descriptor are not
2392 * present when new ACEs are added or removed by changing printer
2393 * permissions through NT. If they are NULL in the new security
2394 * descriptor then copy them over from the old one.
2396 if (!secdesc
->owner_sid
|| !secdesc
->group_sid
) {
2397 struct dom_sid
*owner_sid
, *group_sid
;
2398 struct security_acl
*dacl
, *sacl
;
2401 result
= winreg_get_printer_secdesc(tmp_ctx
,
2405 if (!W_ERROR_IS_OK(result
)) {
2406 talloc_free(tmp_ctx
);
2410 /* Pick out correct owner and group sids */
2411 owner_sid
= secdesc
->owner_sid
?
2412 secdesc
->owner_sid
:
2413 old_secdesc
->owner_sid
;
2415 group_sid
= secdesc
->group_sid
?
2416 secdesc
->group_sid
:
2417 old_secdesc
->group_sid
;
2419 dacl
= secdesc
->dacl
?
2423 sacl
= secdesc
->sacl
?
2427 /* Make a deep copy of the security descriptor */
2428 new_secdesc
= make_sec_desc(tmp_ctx
,
2436 if (new_secdesc
== NULL
) {
2437 talloc_free(tmp_ctx
);
2442 ZERO_STRUCT(hive_hnd
);
2443 ZERO_STRUCT(key_hnd
);
2445 result
= winreg_printer_openkey(tmp_ctx
,
2454 if (!W_ERROR_IS_OK(result
)) {
2458 ndr_err
= ndr_push_struct_blob(&blob
, tmp_ctx
, new_secdesc
,
2459 (ndr_push_flags_fn_t
) ndr_push_security_descriptor
);
2460 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
2461 DEBUG(0, ("winreg_set_secdesc: Failed to marshall security descriptor\n"));
2462 result
= WERR_NOMEM
;
2466 result
= winreg_printer_write_binary(tmp_ctx
,
2473 if (winreg_pipe
!= NULL
) {
2474 if (is_valid_policy_hnd(&key_hnd
)) {
2475 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
2477 if (is_valid_policy_hnd(&hive_hnd
)) {
2478 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
2482 talloc_free(tmp_ctx
);
2486 /* Set printer data over the winreg pipe. */
2487 WERROR
winreg_set_printer_dataex(TALLOC_CTX
*mem_ctx
,
2488 struct auth_serversupplied_info
*server_info
,
2489 const char *printer
,
2492 enum winreg_Type type
,
2496 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2497 struct rpc_pipe_client
*winreg_pipe
= NULL
;
2498 struct policy_handle hive_hnd
, key_hnd
;
2499 struct winreg_String wvalue
;
2501 WERROR result
= WERR_OK
;
2503 TALLOC_CTX
*tmp_ctx
;
2505 tmp_ctx
= talloc_new(mem_ctx
);
2506 if (tmp_ctx
== NULL
) {
2510 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2512 TALLOC_FREE(tmp_ctx
);
2516 ZERO_STRUCT(hive_hnd
);
2517 ZERO_STRUCT(key_hnd
);
2519 DEBUG(8, ("winreg_set_printer_dataex: Open printer key %s, value %s, access_mask: 0x%05x for [%s]\n",
2520 key
, value
, access_mask
, printer
));
2521 result
= winreg_printer_openkey(tmp_ctx
,
2530 if (!W_ERROR_IS_OK(result
)) {
2531 DEBUG(0, ("winreg_set_printer_dataex: Could not open key %s: %s\n",
2532 key
, win_errstr(result
)));
2536 wvalue
.name
= value
;
2537 status
= rpccli_winreg_SetValue(winreg_pipe
,
2545 if (!NT_STATUS_IS_OK(status
)) {
2546 DEBUG(0, ("winreg_set_printer_dataex: Could not set value %s: %s\n",
2547 value
, nt_errstr(status
)));
2548 if (!W_ERROR_IS_OK(result
)) {
2551 result
= ntstatus_to_werror(status
);
2557 if (winreg_pipe
!= NULL
) {
2558 if (is_valid_policy_hnd(&key_hnd
)) {
2559 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
2561 if (is_valid_policy_hnd(&hive_hnd
)) {
2562 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
2566 TALLOC_FREE(tmp_ctx
);
2570 /* Get printer data over a winreg pipe. */
2571 WERROR
winreg_get_printer_dataex(TALLOC_CTX
*mem_ctx
,
2572 struct auth_serversupplied_info
*server_info
,
2573 const char *printer
,
2576 enum winreg_Type
*type
,
2578 uint32_t *data_size
)
2580 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2581 struct rpc_pipe_client
*winreg_pipe
= NULL
;
2582 struct policy_handle hive_hnd
, key_hnd
;
2583 struct winreg_String wvalue
;
2584 enum winreg_Type type_in
;
2587 uint32_t data_in_size
= 0;
2588 uint32_t value_len
= 0;
2589 WERROR result
= WERR_OK
;
2591 TALLOC_CTX
*tmp_ctx
;
2593 tmp_ctx
= talloc_new(mem_ctx
);
2594 if (tmp_ctx
== NULL
) {
2598 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2600 TALLOC_FREE(tmp_ctx
);
2604 ZERO_STRUCT(hive_hnd
);
2605 ZERO_STRUCT(key_hnd
);
2607 result
= winreg_printer_openkey(tmp_ctx
,
2616 if (!W_ERROR_IS_OK(result
)) {
2617 DEBUG(0, ("winreg_get_printer_dataex: Could not open key %s: %s\n",
2618 key
, win_errstr(result
)));
2622 wvalue
.name
= value
;
2625 * call QueryValue once with data == NULL to get the
2626 * needed memory size to be allocated, then allocate
2627 * data buffer and call again.
2629 status
= rpccli_winreg_QueryValue(winreg_pipe
,
2638 if (!NT_STATUS_IS_OK(status
)) {
2639 DEBUG(0, ("winreg_get_printer_dataex: Could not query value %s: %s\n",
2640 value
, nt_errstr(status
)));
2641 if (!W_ERROR_IS_OK(result
)) {
2644 result
= ntstatus_to_werror(status
);
2648 data_in
= (uint8_t *) TALLOC(tmp_ctx
, data_in_size
);
2649 if (data_in
== NULL
) {
2650 result
= WERR_NOMEM
;
2655 status
= rpccli_winreg_QueryValue(winreg_pipe
,
2664 if (!NT_STATUS_IS_OK(status
)) {
2665 DEBUG(0, ("winreg_get_printer_dataex: Could not query value %s: %s\n",
2666 value
, nt_errstr(status
)));
2667 if (!W_ERROR_IS_OK(result
)) {
2668 result
= ntstatus_to_werror(status
);
2674 *data_size
= data_in_size
;
2676 *data
= talloc_move(mem_ctx
, &data_in
);
2681 if (winreg_pipe
!= NULL
) {
2682 if (is_valid_policy_hnd(&key_hnd
)) {
2683 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
2685 if (is_valid_policy_hnd(&hive_hnd
)) {
2686 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
2690 TALLOC_FREE(tmp_ctx
);
2694 /* Enumerate on the values of a given key and provide the data. */
2695 WERROR
winreg_enum_printer_dataex(TALLOC_CTX
*mem_ctx
,
2696 struct auth_serversupplied_info
*server_info
,
2697 const char *printer
,
2699 uint32_t *pnum_values
,
2700 struct spoolss_PrinterEnumValues
**penum_values
)
2702 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2703 struct rpc_pipe_client
*winreg_pipe
= NULL
;
2704 struct policy_handle hive_hnd
, key_hnd
;
2706 struct spoolss_PrinterEnumValues
*enum_values
= NULL
;
2707 uint32_t num_values
= 0;
2709 WERROR result
= WERR_OK
;
2711 TALLOC_CTX
*tmp_ctx
;
2713 tmp_ctx
= talloc_new(mem_ctx
);
2714 if (tmp_ctx
== NULL
) {
2718 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2720 TALLOC_FREE(tmp_ctx
);
2724 result
= winreg_printer_openkey(tmp_ctx
,
2733 if (!W_ERROR_IS_OK(result
)) {
2734 DEBUG(0, ("winreg_enum_printer_dataex: Could not open key %s: %s\n",
2735 key
, win_errstr(result
)));
2739 result
= winreg_printer_enumvalues(tmp_ctx
,
2744 if (!W_ERROR_IS_OK(result
)) {
2745 DEBUG(0, ("winreg_enum_printer_dataex: Could not enumerate values in %s: %s\n",
2746 key
, win_errstr(result
)));
2750 *pnum_values
= num_values
;
2752 *penum_values
= talloc_move(mem_ctx
, &enum_values
);
2757 if (winreg_pipe
!= NULL
) {
2758 if (is_valid_policy_hnd(&key_hnd
)) {
2759 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
2761 if (is_valid_policy_hnd(&hive_hnd
)) {
2762 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
2766 TALLOC_FREE(tmp_ctx
);
2770 /* Delete printer data over a winreg pipe. */
2771 WERROR
winreg_delete_printer_dataex(TALLOC_CTX
*mem_ctx
,
2772 struct auth_serversupplied_info
*server_info
,
2773 const char *printer
,
2777 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2778 struct rpc_pipe_client
*winreg_pipe
= NULL
;
2779 struct policy_handle hive_hnd
, key_hnd
;
2780 struct winreg_String wvalue
;
2782 WERROR result
= WERR_OK
;
2785 TALLOC_CTX
*tmp_ctx
;
2787 tmp_ctx
= talloc_new(mem_ctx
);
2788 if (tmp_ctx
== NULL
) {
2792 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2794 TALLOC_FREE(tmp_ctx
);
2798 ZERO_STRUCT(hive_hnd
);
2799 ZERO_STRUCT(key_hnd
);
2801 result
= winreg_printer_openkey(tmp_ctx
,
2810 if (!W_ERROR_IS_OK(result
)) {
2811 DEBUG(0, ("winreg_delete_printer_dataex: Could not open key %s: %s\n",
2812 key
, win_errstr(result
)));
2816 wvalue
.name
= value
;
2817 status
= rpccli_winreg_DeleteValue(winreg_pipe
,
2822 if (!NT_STATUS_IS_OK(status
)) {
2823 DEBUG(0, ("winreg_delete_printer_dataex: Could not delete value %s: %s\n",
2824 value
, nt_errstr(status
)));
2825 if (!W_ERROR_IS_OK(result
)) {
2828 result
= ntstatus_to_werror(status
);
2834 if (winreg_pipe
!= NULL
) {
2835 if (is_valid_policy_hnd(&key_hnd
)) {
2836 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
2838 if (is_valid_policy_hnd(&hive_hnd
)) {
2839 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
2843 TALLOC_FREE(tmp_ctx
);
2847 /* Enumerate on the subkeys of a given key and provide the data. */
2848 WERROR
winreg_enum_printer_key(TALLOC_CTX
*mem_ctx
,
2849 struct auth_serversupplied_info
*server_info
,
2850 const char *printer
,
2852 uint32_t *pnum_subkeys
,
2853 const char ***psubkeys
)
2855 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2856 struct rpc_pipe_client
*winreg_pipe
= NULL
;
2857 struct policy_handle hive_hnd
, key_hnd
;
2859 const char **subkeys
= NULL
;
2860 uint32_t num_subkeys
= -1;
2862 WERROR result
= WERR_OK
;
2864 TALLOC_CTX
*tmp_ctx
;
2866 tmp_ctx
= talloc_new(mem_ctx
);
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
,
2889 if (!W_ERROR_IS_OK(result
)) {
2890 DEBUG(0, ("winreg_enum_printer_key: Could not open key %s: %s\n",
2891 key
, win_errstr(result
)));
2895 result
= winreg_printer_enumkeys(tmp_ctx
,
2900 if (!W_ERROR_IS_OK(result
)) {
2901 DEBUG(0, ("winreg_enum_printer_key: Could not enumerate subkeys in %s: %s\n",
2902 key
, win_errstr(result
)));
2906 *pnum_subkeys
= num_subkeys
;
2908 *psubkeys
= talloc_move(mem_ctx
, &subkeys
);
2913 if (winreg_pipe
!= NULL
) {
2914 if (is_valid_policy_hnd(&key_hnd
)) {
2915 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
2917 if (is_valid_policy_hnd(&hive_hnd
)) {
2918 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
2922 TALLOC_FREE(tmp_ctx
);
2926 /* Delete a key with subkeys of a given printer. */
2927 WERROR
winreg_delete_printer_key(TALLOC_CTX
*mem_ctx
,
2928 struct auth_serversupplied_info
*server_info
,
2929 const char *printer
,
2932 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2933 struct rpc_pipe_client
*winreg_pipe
= NULL
;
2934 struct policy_handle hive_hnd
, key_hnd
;
2938 TALLOC_CTX
*tmp_ctx
;
2940 tmp_ctx
= talloc_new(mem_ctx
);
2941 if (tmp_ctx
== NULL
) {
2945 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2947 TALLOC_FREE(tmp_ctx
);
2951 result
= winreg_printer_openkey(tmp_ctx
,
2960 if (!W_ERROR_IS_OK(result
)) {
2961 /* key doesn't exist */
2962 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
2967 DEBUG(0, ("winreg_delete_printer_key: Could not open key %s: %s\n",
2968 key
, win_errstr(result
)));
2972 if (is_valid_policy_hnd(&key_hnd
)) {
2973 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
2976 if (key
== NULL
|| key
[0] == '\0') {
2979 keyname
= talloc_asprintf(tmp_ctx
,
2983 if (keyname
== NULL
) {
2984 result
= WERR_NOMEM
;
2989 result
= winreg_printer_delete_subkeys(tmp_ctx
,
2994 if (!W_ERROR_IS_OK(result
)) {
2995 DEBUG(0, ("winreg_delete_printer_key: Could not delete key %s: %s\n",
2996 key
, win_errstr(result
)));
3001 if (winreg_pipe
!= NULL
) {
3002 if (is_valid_policy_hnd(&key_hnd
)) {
3003 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
3005 if (is_valid_policy_hnd(&hive_hnd
)) {
3006 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
3010 TALLOC_FREE(tmp_ctx
);
3014 WERROR
winreg_printer_update_changeid(TALLOC_CTX
*mem_ctx
,
3015 struct auth_serversupplied_info
*server_info
,
3016 const char *printer
)
3018 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3019 struct rpc_pipe_client
*winreg_pipe
= NULL
;
3020 struct policy_handle hive_hnd
, key_hnd
;
3023 TALLOC_CTX
*tmp_ctx
;
3025 tmp_ctx
= talloc_new(mem_ctx
);
3026 if (tmp_ctx
== NULL
) {
3030 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
3032 TALLOC_FREE(tmp_ctx
);
3036 ZERO_STRUCT(hive_hnd
);
3037 ZERO_STRUCT(key_hnd
);
3039 result
= winreg_printer_openkey(tmp_ctx
,
3048 if (!W_ERROR_IS_OK(result
)) {
3049 DEBUG(0, ("winreg_printer_update_changeid: Could not open key %s: %s\n",
3050 path
, win_errstr(result
)));
3054 result
= winreg_printer_write_dword(tmp_ctx
,
3058 winreg_printer_rev_changeid());
3059 if (!W_ERROR_IS_OK(result
)) {
3065 if (winreg_pipe
!= NULL
) {
3066 if (is_valid_policy_hnd(&key_hnd
)) {
3067 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
3069 if (is_valid_policy_hnd(&hive_hnd
)) {
3070 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
3074 TALLOC_FREE(tmp_ctx
);
3078 WERROR
winreg_printer_get_changeid(TALLOC_CTX
*mem_ctx
,
3079 struct auth_serversupplied_info
*server_info
,
3080 const char *printer
,
3081 uint32_t *pchangeid
)
3083 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3084 struct rpc_pipe_client
*winreg_pipe
= NULL
;
3085 struct policy_handle hive_hnd
, key_hnd
;
3086 uint32_t changeid
= 0;
3089 TALLOC_CTX
*tmp_ctx
;
3091 tmp_ctx
= talloc_new(mem_ctx
);
3092 if (tmp_ctx
== NULL
) {
3096 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
3098 TALLOC_FREE(tmp_ctx
);
3102 ZERO_STRUCT(hive_hnd
);
3103 ZERO_STRUCT(key_hnd
);
3105 result
= winreg_printer_openkey(tmp_ctx
,
3114 if (!W_ERROR_IS_OK(result
)) {
3115 DEBUG(0, ("winreg_printer_get_changeid: Could not open key %s: %s\n",
3116 path
, win_errstr(result
)));
3120 DEBUG(0, ("winreg_printer_get_changeid: get changeid from %s\n", path
));
3121 result
= winreg_printer_query_dword(tmp_ctx
,
3126 if (!W_ERROR_IS_OK(result
)) {
3131 *pchangeid
= changeid
;
3136 if (winreg_pipe
!= NULL
) {
3137 if (is_valid_policy_hnd(&key_hnd
)) {
3138 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
3140 if (is_valid_policy_hnd(&hive_hnd
)) {
3141 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
3145 TALLOC_FREE(tmp_ctx
);
3150 * The special behaviour of the spoolss forms is documented at the website:
3152 * Managing Win32 Printserver Forms
3153 * http://unixwiz.net/techtips/winspooler-forms.html
3156 WERROR
winreg_printer_addform1(TALLOC_CTX
*mem_ctx
,
3157 struct auth_serversupplied_info
*server_info
,
3158 struct spoolss_AddFormInfo1
*form
)
3160 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3161 struct rpc_pipe_client
*winreg_pipe
= NULL
;
3162 struct policy_handle hive_hnd
, key_hnd
;
3163 struct winreg_String wvalue
;
3165 uint32_t num_info
= 0;
3166 union spoolss_FormInfo
*info
= NULL
;
3170 TALLOC_CTX
*tmp_ctx
;
3172 tmp_ctx
= talloc_new(mem_ctx
);
3173 if (tmp_ctx
== NULL
) {
3177 ZERO_STRUCT(hive_hnd
);
3178 ZERO_STRUCT(key_hnd
);
3180 result
= winreg_printer_openkey(tmp_ctx
,
3183 TOP_LEVEL_CONTROL_FORMS_KEY
,
3189 if (!W_ERROR_IS_OK(result
)) {
3190 DEBUG(0, ("winreg_printer_addform1: Could not open key %s: %s\n",
3191 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3195 result
= winreg_printer_enumforms1(tmp_ctx
, server_info
, &num_info
, &info
);
3196 if (!W_ERROR_IS_OK(result
)) {
3197 DEBUG(0, ("winreg_printer_addform: Could not enum keys %s: %s\n",
3198 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3202 /* If form name already exists or is builtin return ALREADY_EXISTS */
3203 for (i
= 0; i
< num_info
; i
++) {
3204 if (strequal(info
[i
].info1
.form_name
, form
->form_name
)) {
3205 result
= WERR_FILE_EXISTS
;
3210 wvalue
.name
= form
->form_name
;
3212 blob
= data_blob_talloc(tmp_ctx
, NULL
, 32);
3213 SIVAL(blob
.data
, 0, form
->size
.width
);
3214 SIVAL(blob
.data
, 4, form
->size
.height
);
3215 SIVAL(blob
.data
, 8, form
->area
.left
);
3216 SIVAL(blob
.data
, 12, form
->area
.top
);
3217 SIVAL(blob
.data
, 16, form
->area
.right
);
3218 SIVAL(blob
.data
, 20, form
->area
.bottom
);
3219 SIVAL(blob
.data
, 24, num_info
+ 1); /* FIXME */
3220 SIVAL(blob
.data
, 28, form
->flags
);
3222 status
= rpccli_winreg_SetValue(winreg_pipe
,
3230 if (!NT_STATUS_IS_OK(status
)) {
3231 DEBUG(0, ("winreg_printer_addform1: Could not set value %s: %s\n",
3232 wvalue
.name
, nt_errstr(status
)));
3233 if (!W_ERROR_IS_OK(result
)) {
3236 result
= ntstatus_to_werror(status
);
3242 if (winreg_pipe
!= NULL
) {
3243 if (is_valid_policy_hnd(&key_hnd
)) {
3244 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
3246 if (is_valid_policy_hnd(&hive_hnd
)) {
3247 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
3252 TALLOC_FREE(tmp_ctx
);
3256 WERROR
winreg_printer_enumforms1(TALLOC_CTX
*mem_ctx
,
3257 struct auth_serversupplied_info
*server_info
,
3258 uint32_t *pnum_info
,
3259 union spoolss_FormInfo
**pinfo
)
3261 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3262 struct rpc_pipe_client
*winreg_pipe
= NULL
;
3263 struct policy_handle hive_hnd
, key_hnd
;
3264 union spoolss_FormInfo
*info
;
3265 struct spoolss_PrinterEnumValues
*enum_values
= NULL
;
3266 uint32_t num_values
= 0;
3267 uint32_t num_builtin
= ARRAY_SIZE(builtin_forms1
);
3270 TALLOC_CTX
*tmp_ctx
;
3272 tmp_ctx
= talloc_new(mem_ctx
);
3273 if (tmp_ctx
== NULL
) {
3277 ZERO_STRUCT(hive_hnd
);
3278 ZERO_STRUCT(key_hnd
);
3280 result
= winreg_printer_openkey(tmp_ctx
,
3283 TOP_LEVEL_CONTROL_FORMS_KEY
,
3289 if (!W_ERROR_IS_OK(result
)) {
3290 /* key doesn't exist */
3291 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
3296 DEBUG(0, ("winreg_printer_enumforms1: Could not open key %s: %s\n",
3297 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3301 result
= winreg_printer_enumvalues(tmp_ctx
,
3306 if (!W_ERROR_IS_OK(result
)) {
3307 DEBUG(0, ("winreg_printer_enumforms1: Could not enumerate values in %s: %s\n",
3308 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3312 info
= TALLOC_ARRAY(tmp_ctx
, union spoolss_FormInfo
, num_builtin
+ num_values
);
3314 result
= WERR_NOMEM
;
3318 /* Enumerate BUILTIN forms */
3319 for (i
= 0; i
< num_builtin
; i
++) {
3320 info
[i
].info1
= builtin_forms1
[i
];
3323 /* Enumerate registry forms */
3324 for (i
= 0; i
< num_values
; i
++) {
3325 union spoolss_FormInfo val
;
3327 if (enum_values
[i
].type
!= REG_BINARY
||
3328 enum_values
[i
].data_length
!= 32) {
3332 val
.info1
.form_name
= talloc_strdup(info
, enum_values
[i
].value_name
);
3333 if (val
.info1
.form_name
== NULL
) {
3334 result
= WERR_NOMEM
;
3338 val
.info1
.size
.width
= IVAL(enum_values
[i
].data
->data
, 0);
3339 val
.info1
.size
.height
= IVAL(enum_values
[i
].data
->data
, 4);
3340 val
.info1
.area
.left
= IVAL(enum_values
[i
].data
->data
, 8);
3341 val
.info1
.area
.top
= IVAL(enum_values
[i
].data
->data
, 12);
3342 val
.info1
.area
.right
= IVAL(enum_values
[i
].data
->data
, 16);
3343 val
.info1
.area
.bottom
= IVAL(enum_values
[i
].data
->data
, 20);
3344 /* skip form index IVAL(enum_values[i].data->data, 24)));*/
3345 val
.info1
.flags
= IVAL(enum_values
[i
].data
->data
, 28);
3347 info
[i
+ num_builtin
] = val
;
3350 *pnum_info
= num_builtin
+ num_values
;
3352 *pinfo
= talloc_move(mem_ctx
, &info
);
3356 if (winreg_pipe
!= NULL
) {
3357 if (is_valid_policy_hnd(&key_hnd
)) {
3358 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
3360 if (is_valid_policy_hnd(&hive_hnd
)) {
3361 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
3365 TALLOC_FREE(enum_values
);
3366 TALLOC_FREE(tmp_ctx
);
3370 WERROR
winreg_printer_deleteform1(TALLOC_CTX
*mem_ctx
,
3371 struct auth_serversupplied_info
*server_info
,
3372 const char *form_name
)
3374 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3375 struct rpc_pipe_client
*winreg_pipe
= NULL
;
3376 struct policy_handle hive_hnd
, key_hnd
;
3377 struct winreg_String wvalue
;
3378 uint32_t num_builtin
= ARRAY_SIZE(builtin_forms1
);
3380 WERROR result
= WERR_OK
;
3382 TALLOC_CTX
*tmp_ctx
;
3384 for (i
= 0; i
< num_builtin
; i
++) {
3385 if (strequal(builtin_forms1
[i
].form_name
, form_name
)) {
3386 return WERR_INVALID_PARAMETER
;
3390 tmp_ctx
= talloc_new(mem_ctx
);
3391 if (tmp_ctx
== NULL
) {
3395 ZERO_STRUCT(hive_hnd
);
3396 ZERO_STRUCT(key_hnd
);
3398 result
= winreg_printer_openkey(tmp_ctx
,
3401 TOP_LEVEL_CONTROL_FORMS_KEY
,
3407 if (!W_ERROR_IS_OK(result
)) {
3408 DEBUG(0, ("winreg_printer_deleteform1: Could not open key %s: %s\n",
3409 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3410 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
3411 result
= WERR_INVALID_FORM_NAME
;
3416 wvalue
.name
= form_name
;
3417 status
= rpccli_winreg_DeleteValue(winreg_pipe
,
3422 if (!NT_STATUS_IS_OK(status
)) {
3423 /* If the value doesn't exist, return WERR_INVALID_FORM_NAME */
3424 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
3425 result
= WERR_INVALID_FORM_NAME
;
3428 DEBUG(0, ("winreg_printer_delteform1: Could not delete value %s: %s\n",
3429 wvalue
.name
, nt_errstr(status
)));
3430 if (!W_ERROR_IS_OK(result
)) {
3433 result
= ntstatus_to_werror(status
);
3439 if (winreg_pipe
!= NULL
) {
3440 if (is_valid_policy_hnd(&key_hnd
)) {
3441 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
3443 if (is_valid_policy_hnd(&hive_hnd
)) {
3444 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
3448 TALLOC_FREE(tmp_ctx
);
3452 WERROR
winreg_printer_setform1(TALLOC_CTX
*mem_ctx
,
3453 struct auth_serversupplied_info
*server_info
,
3454 const char *form_name
,
3455 struct spoolss_AddFormInfo1
*form
)
3457 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3458 struct rpc_pipe_client
*winreg_pipe
= NULL
;
3459 struct policy_handle hive_hnd
, key_hnd
;
3460 struct winreg_String wvalue
;
3462 uint32_t num_builtin
= ARRAY_SIZE(builtin_forms1
);
3466 TALLOC_CTX
*tmp_ctx
= NULL
;
3468 for (i
= 0; i
< num_builtin
; i
++) {
3469 if (strequal(builtin_forms1
[i
].form_name
, form
->form_name
)) {
3470 result
= WERR_INVALID_PARAM
;
3475 tmp_ctx
= talloc_new(mem_ctx
);
3476 if (tmp_ctx
== NULL
) {
3480 ZERO_STRUCT(hive_hnd
);
3481 ZERO_STRUCT(key_hnd
);
3483 result
= winreg_printer_openkey(tmp_ctx
,
3486 TOP_LEVEL_CONTROL_FORMS_KEY
,
3492 if (!W_ERROR_IS_OK(result
)) {
3493 DEBUG(0, ("winreg_printer_setform1: Could not open key %s: %s\n",
3494 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3498 /* If form_name != form->form_name then we renamed the form */
3499 if (strequal(form_name
, form
->form_name
)) {
3500 result
= winreg_printer_deleteform1(tmp_ctx
, server_info
, form_name
);
3501 if (!W_ERROR_IS_OK(result
)) {
3502 DEBUG(0, ("winreg_printer_setform1: Could not open key %s: %s\n",
3503 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3508 wvalue
.name
= form
->form_name
;
3510 blob
= data_blob_talloc(tmp_ctx
, NULL
, 32);
3511 SIVAL(blob
.data
, 0, form
->size
.width
);
3512 SIVAL(blob
.data
, 4, form
->size
.height
);
3513 SIVAL(blob
.data
, 8, form
->area
.left
);
3514 SIVAL(blob
.data
, 12, form
->area
.top
);
3515 SIVAL(blob
.data
, 16, form
->area
.right
);
3516 SIVAL(blob
.data
, 20, form
->area
.bottom
);
3517 SIVAL(blob
.data
, 24, 42);
3518 SIVAL(blob
.data
, 28, form
->flags
);
3520 status
= rpccli_winreg_SetValue(winreg_pipe
,
3528 if (!NT_STATUS_IS_OK(status
)) {
3529 DEBUG(0, ("winreg_printer_setform1: Could not set value %s: %s\n",
3530 wvalue
.name
, nt_errstr(status
)));
3531 if (!W_ERROR_IS_OK(result
)) {
3534 result
= ntstatus_to_werror(status
);
3540 if (winreg_pipe
!= NULL
) {
3541 if (is_valid_policy_hnd(&key_hnd
)) {
3542 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
3544 if (is_valid_policy_hnd(&hive_hnd
)) {
3545 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
3549 TALLOC_FREE(tmp_ctx
);
3553 WERROR
winreg_printer_getform1(TALLOC_CTX
*mem_ctx
,
3554 struct auth_serversupplied_info
*server_info
,
3555 const char *form_name
,
3556 struct spoolss_FormInfo1
*r
)
3558 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3559 struct rpc_pipe_client
*winreg_pipe
= NULL
;
3560 struct policy_handle hive_hnd
, key_hnd
;
3561 struct winreg_String wvalue
;
3562 enum winreg_Type type_in
;
3564 uint32_t data_in_size
= 0;
3565 uint32_t value_len
= 0;
3566 uint32_t num_builtin
= ARRAY_SIZE(builtin_forms1
);
3570 TALLOC_CTX
*tmp_ctx
;
3572 /* check builtin forms first */
3573 for (i
= 0; i
< num_builtin
; i
++) {
3574 if (strequal(builtin_forms1
[i
].form_name
, form_name
)) {
3575 *r
= builtin_forms1
[i
];
3580 tmp_ctx
= talloc_new(mem_ctx
);
3581 if (tmp_ctx
== NULL
) {
3585 ZERO_STRUCT(hive_hnd
);
3586 ZERO_STRUCT(key_hnd
);
3588 result
= winreg_printer_openkey(tmp_ctx
,
3591 TOP_LEVEL_CONTROL_FORMS_KEY
,
3597 if (!W_ERROR_IS_OK(result
)) {
3598 DEBUG(0, ("winreg_printer_getform1: Could not open key %s: %s\n",
3599 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3603 wvalue
.name
= form_name
;
3606 * call QueryValue once with data == NULL to get the
3607 * needed memory size to be allocated, then allocate
3608 * data buffer and call again.
3610 status
= rpccli_winreg_QueryValue(winreg_pipe
,
3619 if (!NT_STATUS_IS_OK(status
)) {
3620 DEBUG(0, ("winreg_printer_getform1: Could not query value %s: %s\n",
3621 wvalue
.name
, nt_errstr(status
)));
3622 if (!W_ERROR_IS_OK(result
)) {
3625 result
= ntstatus_to_werror(status
);
3629 data_in
= (uint8_t *) TALLOC(tmp_ctx
, data_in_size
);
3630 if (data_in
== NULL
) {
3631 result
= WERR_NOMEM
;
3636 status
= rpccli_winreg_QueryValue(winreg_pipe
,
3645 if (!NT_STATUS_IS_OK(status
)) {
3646 DEBUG(0, ("winreg_printer_getform1: Could not query value %s: %s\n",
3647 wvalue
.name
, nt_errstr(status
)));
3648 if (!W_ERROR_IS_OK(result
)) {
3651 result
= ntstatus_to_werror(status
);
3655 r
->form_name
= talloc_strdup(mem_ctx
, form_name
);
3656 if (r
->form_name
== NULL
) {
3657 result
= WERR_NOMEM
;
3661 r
->size
.width
= IVAL(data_in
, 0);
3662 r
->size
.height
= IVAL(data_in
, 4);
3663 r
->area
.left
= IVAL(data_in
, 8);
3664 r
->area
.top
= IVAL(data_in
, 12);
3665 r
->area
.right
= IVAL(data_in
, 16);
3666 r
->area
.bottom
= IVAL(data_in
, 20);
3667 /* skip index IVAL(data_in, 24)));*/
3668 r
->flags
= IVAL(data_in
, 28);
3672 if (winreg_pipe
!= NULL
) {
3673 if (is_valid_policy_hnd(&key_hnd
)) {
3674 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
3676 if (is_valid_policy_hnd(&hive_hnd
)) {
3677 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
3681 TALLOC_FREE(tmp_ctx
);
3685 WERROR
winreg_add_driver(TALLOC_CTX
*mem_ctx
,
3686 struct auth_serversupplied_info
*server_info
,
3687 struct spoolss_AddDriverInfoCtr
*r
,
3688 const char **driver_name
,
3689 uint32_t *driver_version
)
3691 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3692 struct rpc_pipe_client
*winreg_pipe
= NULL
;
3693 struct policy_handle hive_hnd
, key_hnd
;
3694 struct spoolss_DriverInfo8 info8
;
3695 TALLOC_CTX
*tmp_ctx
= NULL
;
3698 ZERO_STRUCT(hive_hnd
);
3699 ZERO_STRUCT(key_hnd
);
3702 if (!driver_info_ctr_to_info8(r
, &info8
)) {
3703 result
= WERR_INVALID_PARAMETER
;
3707 tmp_ctx
= talloc_new(mem_ctx
);
3708 if (tmp_ctx
== NULL
) {
3712 result
= winreg_printer_opendriver(tmp_ctx
,
3721 if (!W_ERROR_IS_OK(result
)) {
3722 DEBUG(0, ("winreg_add_driver: "
3723 "Could not open driver key (%s,%s,%d): %s\n",
3724 info8
.driver_name
, info8
.architecture
,
3725 info8
.version
, win_errstr(result
)));
3729 /* TODO: "Attributes" ? */
3731 result
= winreg_printer_write_dword(tmp_ctx
, winreg_pipe
,
3732 &key_hnd
, "Version",
3734 if (!W_ERROR_IS_OK(result
)) {
3738 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3741 if (!W_ERROR_IS_OK(result
)) {
3745 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3746 &key_hnd
, "Data File",
3748 if (!W_ERROR_IS_OK(result
)) {
3752 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3753 &key_hnd
, "Configuration File",
3755 if (!W_ERROR_IS_OK(result
)) {
3759 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3760 &key_hnd
, "Help File",
3762 if (!W_ERROR_IS_OK(result
)) {
3766 result
= winreg_printer_write_multi_sz(tmp_ctx
, winreg_pipe
,
3767 &key_hnd
, "Dependent Files",
3768 info8
.dependent_files
);
3769 if (!W_ERROR_IS_OK(result
)) {
3773 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3774 &key_hnd
, "Monitor",
3775 info8
.monitor_name
);
3776 if (!W_ERROR_IS_OK(result
)) {
3780 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3781 &key_hnd
, "Datatype",
3782 info8
.default_datatype
);
3783 if (!W_ERROR_IS_OK(result
)) {
3787 result
= winreg_printer_write_multi_sz(tmp_ctx
, winreg_pipe
,
3788 &key_hnd
, "Previous Names",
3789 info8
.previous_names
);
3790 if (!W_ERROR_IS_OK(result
)) {
3794 result
= winreg_printer_write_date(tmp_ctx
, winreg_pipe
,
3795 &key_hnd
, "DriverDate",
3797 if (!W_ERROR_IS_OK(result
)) {
3801 result
= winreg_printer_write_ver(tmp_ctx
, winreg_pipe
,
3802 &key_hnd
, "DriverVersion",
3803 info8
.driver_version
);
3804 if (!W_ERROR_IS_OK(result
)) {
3808 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3809 &key_hnd
, "Manufacturer",
3810 info8
.manufacturer_name
);
3811 if (!W_ERROR_IS_OK(result
)) {
3815 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3816 &key_hnd
, "OEM URL",
3817 info8
.manufacturer_url
);
3818 if (!W_ERROR_IS_OK(result
)) {
3822 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3823 &key_hnd
, "HardwareID",
3825 if (!W_ERROR_IS_OK(result
)) {
3829 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3830 &key_hnd
, "Provider",
3832 if (!W_ERROR_IS_OK(result
)) {
3836 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3837 &key_hnd
, "Print Processor",
3838 info8
.print_processor
);
3839 if (!W_ERROR_IS_OK(result
)) {
3843 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3844 &key_hnd
, "VendorSetup",
3845 info8
.vendor_setup
);
3846 if (!W_ERROR_IS_OK(result
)) {
3850 result
= winreg_printer_write_multi_sz(tmp_ctx
, winreg_pipe
,
3851 &key_hnd
, "Color Profiles",
3852 info8
.color_profiles
);
3853 if (!W_ERROR_IS_OK(result
)) {
3857 result
= winreg_printer_write_sz(tmp_ctx
, winreg_pipe
,
3858 &key_hnd
, "InfPath",
3860 if (!W_ERROR_IS_OK(result
)) {
3864 result
= winreg_printer_write_dword(tmp_ctx
, winreg_pipe
, &key_hnd
,
3865 "PrinterDriverAttributes",
3866 info8
.printer_driver_attributes
);
3867 if (!W_ERROR_IS_OK(result
)) {
3871 result
= winreg_printer_write_multi_sz(tmp_ctx
, winreg_pipe
,
3872 &key_hnd
, "CoreDependencies",
3873 info8
.core_driver_dependencies
);
3874 if (!W_ERROR_IS_OK(result
)) {
3878 result
= winreg_printer_write_date(tmp_ctx
, winreg_pipe
,
3879 &key_hnd
, "MinInboxDriverVerDate",
3880 info8
.min_inbox_driver_ver_date
);
3881 if (!W_ERROR_IS_OK(result
)) {
3885 result
= winreg_printer_write_ver(tmp_ctx
, winreg_pipe
, &key_hnd
,
3886 "MinInboxDriverVerVersion",
3887 info8
.min_inbox_driver_ver_version
);
3888 if (!W_ERROR_IS_OK(result
)) {
3892 *driver_name
= info8
.driver_name
;
3893 *driver_version
= info8
.version
;
3896 if (winreg_pipe
!= NULL
) {
3897 if (is_valid_policy_hnd(&key_hnd
)) {
3898 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
3900 if (is_valid_policy_hnd(&hive_hnd
)) {
3901 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
3905 TALLOC_FREE(tmp_ctx
);
3909 WERROR
winreg_get_driver(TALLOC_CTX
*mem_ctx
,
3910 struct auth_serversupplied_info
*server_info
,
3911 const char *architecture
,
3912 const char *driver_name
,
3913 uint32_t driver_version
,
3914 struct spoolss_DriverInfo8
**_info8
)
3916 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3917 struct rpc_pipe_client
*winreg_pipe
= NULL
;
3918 struct policy_handle hive_hnd
, key_hnd
;
3919 struct spoolss_DriverInfo8 i8
, *info8
;
3920 struct spoolss_PrinterEnumValues
*enum_values
= NULL
;
3921 struct spoolss_PrinterEnumValues
*v
;
3922 uint32_t num_values
= 0;
3923 TALLOC_CTX
*tmp_ctx
;
3927 ZERO_STRUCT(hive_hnd
);
3928 ZERO_STRUCT(key_hnd
);
3931 tmp_ctx
= talloc_new(mem_ctx
);
3932 if (tmp_ctx
== NULL
) {
3936 if (driver_version
== DRIVER_ANY_VERSION
) {
3937 /* look for Win2k first and then for NT4 */
3938 result
= winreg_printer_opendriver(tmp_ctx
,
3947 if (!W_ERROR_IS_OK(result
)) {
3948 result
= winreg_printer_opendriver(tmp_ctx
,
3959 /* ok normal case */
3960 result
= winreg_printer_opendriver(tmp_ctx
,
3970 if (!W_ERROR_IS_OK(result
)) {
3971 DEBUG(5, ("winreg_get_driver: "
3972 "Could not open driver key (%s,%s,%d): %s\n",
3973 driver_name
, architecture
,
3974 driver_version
, win_errstr(result
)));
3978 result
= winreg_printer_enumvalues(tmp_ctx
,
3983 if (!W_ERROR_IS_OK(result
)) {
3984 DEBUG(0, ("winreg_get_driver: "
3985 "Could not enumerate values for (%s,%s,%d): %s\n",
3986 driver_name
, architecture
,
3987 driver_version
, win_errstr(result
)));
3991 info8
= talloc_zero(tmp_ctx
, struct spoolss_DriverInfo8
);
3992 if (info8
== NULL
) {
3993 result
= WERR_NOMEM
;
3997 info8
->driver_name
= talloc_strdup(info8
, driver_name
);
3998 if (info8
->driver_name
== NULL
) {
3999 result
= WERR_NOMEM
;
4003 info8
->architecture
= talloc_strdup(info8
, architecture
);
4004 if (info8
->architecture
== NULL
) {
4005 result
= WERR_NOMEM
;
4009 info8
->config_file
= EMPTY_STRING
;
4010 info8
->data_file
= EMPTY_STRING
;
4011 info8
->default_datatype
= EMPTY_STRING
;
4012 info8
->driver_path
= EMPTY_STRING
;
4013 info8
->hardware_id
= EMPTY_STRING
;
4014 info8
->help_file
= EMPTY_STRING
;
4015 info8
->inf_path
= EMPTY_STRING
;
4016 info8
->manufacturer_name
= EMPTY_STRING
;
4017 info8
->manufacturer_url
= EMPTY_STRING
;
4018 info8
->monitor_name
= EMPTY_STRING
;
4019 info8
->print_processor
= EMPTY_STRING
;
4020 info8
->provider
= EMPTY_STRING
;
4021 info8
->vendor_setup
= EMPTY_STRING
;
4023 info8
->color_profiles
= empty_string_array
;
4024 info8
->core_driver_dependencies
= EMPTY_STRING_ARRAY
;
4025 info8
->dependent_files
= EMPTY_STRING_ARRAY
;
4026 info8
->previous_names
= EMPTY_STRING_ARRAY
;
4030 for (i
= 0; i
< num_values
; i
++) {
4031 const char *tmp_str
;
4033 v
= &enum_values
[i
];
4035 result
= winreg_enumval_to_dword(info8
, v
,
4038 CHECK_ERROR(result
);
4040 result
= winreg_enumval_to_sz(info8
, v
,
4042 &info8
->driver_path
);
4043 CHECK_ERROR(result
);
4045 result
= winreg_enumval_to_sz(info8
, v
,
4048 CHECK_ERROR(result
);
4050 result
= winreg_enumval_to_sz(info8
, v
,
4051 "Configuration File",
4052 &info8
->config_file
);
4053 CHECK_ERROR(result
);
4055 result
= winreg_enumval_to_sz(info8
, v
,
4058 CHECK_ERROR(result
);
4060 result
= winreg_enumval_to_multi_sz(info8
, v
,
4062 &info8
->dependent_files
);
4063 CHECK_ERROR(result
);
4065 result
= winreg_enumval_to_sz(info8
, v
,
4067 &info8
->monitor_name
);
4068 CHECK_ERROR(result
);
4070 result
= winreg_enumval_to_sz(info8
, v
,
4072 &info8
->default_datatype
);
4073 CHECK_ERROR(result
);
4075 result
= winreg_enumval_to_multi_sz(info8
, v
,
4077 &info8
->previous_names
);
4078 CHECK_ERROR(result
);
4080 result
= winreg_enumval_to_sz(info8
, v
,
4083 if (W_ERROR_IS_OK(result
)) {
4084 result
= winreg_printer_date_to_NTTIME(tmp_str
,
4085 &info8
->driver_date
);
4087 CHECK_ERROR(result
);
4089 result
= winreg_enumval_to_sz(info8
, v
,
4092 if (W_ERROR_IS_OK(result
)) {
4093 result
= winreg_printer_ver_to_dword(tmp_str
,
4094 &info8
->driver_version
);
4096 CHECK_ERROR(result
);
4098 result
= winreg_enumval_to_sz(info8
, v
,
4100 &info8
->manufacturer_name
);
4101 CHECK_ERROR(result
);
4103 result
= winreg_enumval_to_sz(info8
, v
,
4105 &info8
->manufacturer_url
);
4106 CHECK_ERROR(result
);
4108 result
= winreg_enumval_to_sz(info8
, v
,
4110 &info8
->hardware_id
);
4111 CHECK_ERROR(result
);
4113 result
= winreg_enumval_to_sz(info8
, v
,
4116 CHECK_ERROR(result
);
4118 result
= winreg_enumval_to_sz(info8
, v
,
4120 &info8
->print_processor
);
4121 CHECK_ERROR(result
);
4123 result
= winreg_enumval_to_sz(info8
, v
,
4125 &info8
->vendor_setup
);
4126 CHECK_ERROR(result
);
4128 result
= winreg_enumval_to_multi_sz(info8
, v
,
4130 &info8
->color_profiles
);
4131 CHECK_ERROR(result
);
4133 result
= winreg_enumval_to_sz(info8
, v
,
4136 CHECK_ERROR(result
);
4138 result
= winreg_enumval_to_dword(info8
, v
,
4139 "PrinterDriverAttributes",
4140 &info8
->printer_driver_attributes
);
4141 CHECK_ERROR(result
);
4143 result
= winreg_enumval_to_multi_sz(info8
, v
,
4145 &info8
->core_driver_dependencies
);
4146 CHECK_ERROR(result
);
4148 result
= winreg_enumval_to_sz(info8
, v
,
4149 "MinInboxDriverVerDate",
4151 if (W_ERROR_IS_OK(result
)) {
4152 result
= winreg_printer_date_to_NTTIME(tmp_str
,
4153 &info8
->min_inbox_driver_ver_date
);
4155 CHECK_ERROR(result
);
4157 result
= winreg_enumval_to_sz(info8
, v
,
4158 "MinInboxDriverVerVersion",
4160 if (W_ERROR_IS_OK(result
)) {
4161 result
= winreg_printer_ver_to_dword(tmp_str
,
4162 &info8
->min_inbox_driver_ver_version
);
4164 CHECK_ERROR(result
);
4167 if (!W_ERROR_IS_OK(result
)) {
4168 DEBUG(0, ("winreg_enumval_to_TYPE() failed "
4169 "for %s: %s\n", v
->value_name
,
4170 win_errstr(result
)));
4174 *_info8
= talloc_steal(mem_ctx
, info8
);
4177 if (winreg_pipe
!= NULL
) {
4178 if (is_valid_policy_hnd(&key_hnd
)) {
4179 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
4181 if (is_valid_policy_hnd(&hive_hnd
)) {
4182 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
4186 TALLOC_FREE(tmp_ctx
);
4190 WERROR
winreg_del_driver(TALLOC_CTX
*mem_ctx
,
4191 struct auth_serversupplied_info
*server_info
,
4192 struct spoolss_DriverInfo8
*info8
,
4195 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4196 struct rpc_pipe_client
*winreg_pipe
= NULL
;
4197 struct policy_handle hive_hnd
, key_hnd
;
4198 TALLOC_CTX
*tmp_ctx
;
4202 ZERO_STRUCT(hive_hnd
);
4203 ZERO_STRUCT(key_hnd
);
4205 tmp_ctx
= talloc_new(mem_ctx
);
4206 if (tmp_ctx
== NULL
) {
4210 /* test that the key exists */
4211 result
= winreg_printer_opendriver(tmp_ctx
,
4214 info8
->architecture
,
4220 if (!W_ERROR_IS_OK(result
)) {
4221 /* key doesn't exist */
4222 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
4227 DEBUG(5, ("winreg_del_driver: "
4228 "Could not open driver (%s,%s,%u): %s\n",
4229 info8
->driver_name
, info8
->architecture
,
4230 version
, win_errstr(result
)));
4235 if (is_valid_policy_hnd(&key_hnd
)) {
4236 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
4239 key_name
= talloc_asprintf(tmp_ctx
,
4240 "%s\\Environments\\%s\\Drivers\\Version-%u",
4241 TOP_LEVEL_CONTROL_KEY
,
4242 info8
->architecture
, version
);
4243 if (key_name
== NULL
) {
4244 result
= WERR_NOMEM
;
4248 result
= winreg_printer_delete_subkeys(tmp_ctx
,
4253 if (!W_ERROR_IS_OK(result
)) {
4254 DEBUG(0, ("winreg_del_driver: "
4255 "Could not open driver (%s,%s,%u): %s\n",
4256 info8
->driver_name
, info8
->architecture
,
4257 version
, win_errstr(result
)));
4263 if (winreg_pipe
!= NULL
) {
4264 if (is_valid_policy_hnd(&key_hnd
)) {
4265 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
4267 if (is_valid_policy_hnd(&hive_hnd
)) {
4268 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
4272 TALLOC_FREE(tmp_ctx
);
4276 WERROR
winreg_get_driver_list(TALLOC_CTX
*mem_ctx
,
4277 struct auth_serversupplied_info
*server_info
,
4278 const char *architecture
,
4280 uint32_t *num_drivers
,
4281 const char ***drivers_p
)
4283 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4284 struct rpc_pipe_client
*winreg_pipe
= NULL
;
4285 struct policy_handle hive_hnd
, key_hnd
;
4286 const char **drivers
;
4287 TALLOC_CTX
*tmp_ctx
;
4293 ZERO_STRUCT(hive_hnd
);
4294 ZERO_STRUCT(key_hnd
);
4296 tmp_ctx
= talloc_new(mem_ctx
);
4297 if (tmp_ctx
== NULL
) {
4301 /* use NULL for the driver name so we open the key that is
4302 * parent of all drivers for this architecture and version */
4303 result
= winreg_printer_opendriver(tmp_ctx
,
4312 if (!W_ERROR_IS_OK(result
)) {
4313 DEBUG(5, ("winreg_get_driver_list: "
4314 "Could not open key (%s,%u): %s\n",
4315 architecture
, version
, win_errstr(result
)));
4320 result
= winreg_printer_enumkeys(tmp_ctx
,
4325 if (!W_ERROR_IS_OK(result
)) {
4326 DEBUG(0, ("winreg_get_driver_list: "
4327 "Could not enumerate drivers for (%s,%u): %s\n",
4328 architecture
, version
, win_errstr(result
)));
4332 *drivers_p
= talloc_steal(mem_ctx
, drivers
);
4336 if (winreg_pipe
!= NULL
) {
4337 if (is_valid_policy_hnd(&key_hnd
)) {
4338 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
4340 if (is_valid_policy_hnd(&hive_hnd
)) {
4341 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
4345 TALLOC_FREE(tmp_ctx
);