s3-spoolss: Get rid of get_server_name.
[amitay/samba.git] / source3 / printing / nt_printing.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-2000,
5  *  Copyright (C) Jean François Micouleau      1998-2000.
6  *  Copyright (C) Gerald Carter                2002-2005.
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 3 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include "includes.h"
23 #include "librpc/gen_ndr/messaging.h"
24 #include "printing/pcap.h"
25 #include "registry.h"
26 #include "registry/reg_objects.h"
27 #include "../librpc/gen_ndr/ndr_security.h"
28 #include "rpc_server/srv_spoolss_util.h"
29
30 #include "../rpc_server/srv_spoolss_util.h"
31
32 static TDB_CONTEXT *tdb_forms; /* used for forms files */
33 static TDB_CONTEXT *tdb_drivers; /* used for driver files */
34 static TDB_CONTEXT *tdb_printers; /* used for printers files */
35
36 #define FORMS_PREFIX "FORMS/"
37 #define DRIVERS_PREFIX "DRIVERS/"
38 #define PRINTERS_PREFIX "PRINTERS/"
39 #define SECDESC_PREFIX "SECDESC/"
40 #define GLOBAL_C_SETPRINTER "GLOBALS/c_setprinter"
41
42 #define NTDRIVERS_DATABASE_VERSION_1 1
43 #define NTDRIVERS_DATABASE_VERSION_2 2
44 #define NTDRIVERS_DATABASE_VERSION_3 3 /* little endian version of v2 */
45 #define NTDRIVERS_DATABASE_VERSION_4 4 /* fix generic bits in security descriptors */
46 #define NTDRIVERS_DATABASE_VERSION_5 5 /* normalize keys in ntprinters.tdb */
47
48 /* Map generic permissions to printer object specific permissions */
49
50 const struct generic_mapping printer_generic_mapping = {
51         PRINTER_READ,
52         PRINTER_WRITE,
53         PRINTER_EXECUTE,
54         PRINTER_ALL_ACCESS
55 };
56
57 const struct standard_mapping printer_std_mapping = {
58         PRINTER_READ,
59         PRINTER_WRITE,
60         PRINTER_EXECUTE,
61         PRINTER_ALL_ACCESS
62 };
63
64 /* Map generic permissions to print server object specific permissions */
65
66 const struct generic_mapping printserver_generic_mapping = {
67         SERVER_READ,
68         SERVER_WRITE,
69         SERVER_EXECUTE,
70         SERVER_ALL_ACCESS
71 };
72
73 const struct generic_mapping printserver_std_mapping = {
74         SERVER_READ,
75         SERVER_WRITE,
76         SERVER_EXECUTE,
77         SERVER_ALL_ACCESS
78 };
79
80 /* Map generic permissions to job object specific permissions */
81
82 const struct generic_mapping job_generic_mapping = {
83         JOB_READ,
84         JOB_WRITE,
85         JOB_EXECUTE,
86         JOB_ALL_ACCESS
87 };
88
89 /* We need one default form to support our default printer. Msoft adds the
90 forms it wants and in the ORDER it wants them (note: DEVMODE papersize is an
91 array index). Letter is always first, so (for the current code) additions
92 always put things in the correct order. */
93 static const nt_forms_struct default_forms[] = {
94         {"Letter",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
95         {"Letter Small",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
96         {"Tabloid",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
97         {"Ledger",0x1,0x696b8,0x44368,0x0,0x0,0x696b8,0x44368},
98         {"Legal",0x1,0x34b5c,0x56d10,0x0,0x0,0x34b5c,0x56d10},
99         {"Statement",0x1,0x221b4,0x34b5c,0x0,0x0,0x221b4,0x34b5c},
100         {"Executive",0x1,0x2cf56,0x411cc,0x0,0x0,0x2cf56,0x411cc},
101         {"A0",0x1,0xcd528,0x122488,0x0,0x0,0xcd528,0x122488},
102         {"A1",0x1,0x91050,0xcd528,0x0,0x0,0x91050,0xcd528},
103         {"A3",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
104         {"A4",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
105         {"A4 Small",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
106         {"A5",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
107         {"B4 (JIS)",0x1,0x3ebe8,0x58de0,0x0,0x0,0x3ebe8,0x58de0},
108         {"B5 (JIS)",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
109         {"Folio",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
110         {"Quarto",0x1,0x347d8,0x43238,0x0,0x0,0x347d8,0x43238},
111         {"10x14",0x1,0x3e030,0x56d10,0x0,0x0,0x3e030,0x56d10},
112         {"11x17",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
113         {"Note",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
114         {"Envelope #9",0x1,0x18079,0x37091,0x0,0x0,0x18079,0x37091},
115         {"Envelope #10",0x1,0x19947,0x3ae94,0x0,0x0,0x19947,0x3ae94},
116         {"Envelope #11",0x1,0x1be7c,0x40565,0x0,0x0,0x1be7c,0x40565},
117         {"Envelope #12",0x1,0x1d74a,0x44368,0x0,0x0,0x1d74a,0x44368},
118         {"Envelope #14",0x1,0x1f018,0x47504,0x0,0x0,0x1f018,0x47504},
119         {"C size sheet",0x1,0x696b8,0x886d0,0x0,0x0,0x696b8,0x886d0},
120         {"D size sheet",0x1,0x886d0,0xd2d70,0x0,0x0,0x886d0,0xd2d70},
121         {"E size sheet",0x1,0xd2d70,0x110da0,0x0,0x0,0xd2d70,0x110da0},
122         {"Envelope DL",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
123         {"Envelope C5",0x1,0x278d0,0x37e88,0x0,0x0,0x278d0,0x37e88},
124         {"Envelope C3",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
125         {"Envelope C4",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
126         {"Envelope C6",0x1,0x1bd50,0x278d0,0x0,0x0,0x1bd50,0x278d0},
127         {"Envelope C65",0x1,0x1bd50,0x37e88,0x0,0x0,0x1bd50,0x37e88},
128         {"Envelope B4",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
129         {"Envelope B5",0x1,0x2af80,0x3d090,0x0,0x0,0x2af80,0x3d090},
130         {"Envelope B6",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
131         {"Envelope",0x1,0x1adb0,0x38270,0x0,0x0,0x1adb0,0x38270},
132         {"Envelope Monarch",0x1,0x18079,0x2e824,0x0,0x0,0x18079,0x2e824},
133         {"6 3/4 Envelope",0x1,0x167ab,0x284ec,0x0,0x0,0x167ab,0x284ec},
134         {"US Std Fanfold",0x1,0x5c3e1,0x44368,0x0,0x0,0x5c3e1,0x44368},
135         {"German Std Fanfold",0x1,0x34b5c,0x4a6a0,0x0,0x0,0x34b5c,0x4a6a0},
136         {"German Legal Fanfold",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
137         {"B4 (ISO)",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
138         {"Japanese Postcard",0x1,0x186a0,0x24220,0x0,0x0,0x186a0,0x24220},
139         {"9x11",0x1,0x37cf8,0x44368,0x0,0x0,0x37cf8,0x44368},
140         {"10x11",0x1,0x3e030,0x44368,0x0,0x0,0x3e030,0x44368},
141         {"15x11",0x1,0x5d048,0x44368,0x0,0x0,0x5d048,0x44368},
142         {"Envelope Invite",0x1,0x35b60,0x35b60,0x0,0x0,0x35b60,0x35b60},
143         {"Reserved48",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
144         {"Reserved49",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
145         {"Letter Extra",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
146         {"Legal Extra",0x1,0x3ae94,0x5d048,0x0,0x0,0x3ae94,0x5d048},
147         {"Tabloid Extra",0x1,0x4a6a0,0x6f9f0,0x0,0x0,0x4a6a0,0x6f9f0},
148         {"A4 Extra",0x1,0x397c2,0x4eb16,0x0,0x0,0x397c2,0x4eb16},
149         {"Letter Transverse",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
150         {"A4 Transverse",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
151         {"Letter Extra Transverse",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
152         {"Super A",0x1,0x376b8,0x56ea0,0x0,0x0,0x376b8,0x56ea0},
153         {"Super B",0x1,0x4a768,0x76e58,0x0,0x0,0x4a768,0x76e58},
154         {"Letter Plus",0x1,0x34b5c,0x4eb16,0x0,0x0,0x34b5c,0x4eb16},
155         {"A4 Plus",0x1,0x33450,0x50910,0x0,0x0,0x33450,0x50910},
156         {"A5 Transverse",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
157         {"B5 (JIS) Transverse",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
158         {"A3 Extra",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
159         {"A5 Extra",0x1,0x2a7b0,0x395f8,0x0,0x0,0x2a7b0,0x395f8},
160         {"B5 (ISO) Extra",0x1,0x31128,0x43620,0x0,0x0,0x31128,0x43620},
161         {"A2",0x1,0x668a0,0x91050,0x0,0x0,0x668a0,0x91050},
162         {"A3 Transverse",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
163         {"A3 Extra Transverse",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
164         {"Japanese Double Postcard",0x1,0x30d40,0x24220,0x0,0x0,0x30d40,0x24220},
165         {"A6",0x1,0x19a28,0x24220,0x0,0x0,0x19a28,0x24220},
166         {"Japanese Envelope Kaku #2",0x1,0x3a980,0x510e0,0x0,0x0,0x3a980,0x510e0},
167         {"Japanese Envelope Kaku #3",0x1,0x34bc0,0x43a08,0x0,0x0,0x34bc0,0x43a08},
168         {"Japanese Envelope Chou #3",0x1,0x1d4c0,0x395f8,0x0,0x0,0x1d4c0,0x395f8},
169         {"Japanese Envelope Chou #4",0x1,0x15f90,0x320c8,0x0,0x0,0x15f90,0x320c8},
170         {"Letter Rotated",0x1,0x44368,0x34b5c,0x0,0x0,0x44368,0x34b5c},
171         {"A3 Rotated",0x1,0x668a0,0x48828,0x0,0x0,0x668a0,0x48828},
172         {"A4 Rotated",0x1,0x48828,0x33450,0x0,0x0,0x48828,0x33450},
173         {"A5 Rotated",0x1,0x33450,0x24220,0x0,0x0,0x33450,0x24220},
174         {"B4 (JIS) Rotated",0x1,0x58de0,0x3ebe8,0x0,0x0,0x58de0,0x3ebe8},
175         {"B5 (JIS) Rotated",0x1,0x3ebe8,0x2c6f0,0x0,0x0,0x3ebe8,0x2c6f0},
176         {"Japanese Postcard Rotated",0x1,0x24220,0x186a0,0x0,0x0,0x24220,0x186a0},
177         {"Double Japan Postcard Rotated",0x1,0x24220,0x30d40,0x0,0x0,0x24220,0x30d40},
178         {"A6 Rotated",0x1,0x24220,0x19a28,0x0,0x0,0x24220,0x19a28},
179         {"Japan Envelope Kaku #2 Rotated",0x1,0x510e0,0x3a980,0x0,0x0,0x510e0,0x3a980},
180         {"Japan Envelope Kaku #3 Rotated",0x1,0x43a08,0x34bc0,0x0,0x0,0x43a08, 0x34bc0},
181         {"Japan Envelope Chou #3 Rotated",0x1,0x395f8,0x1d4c0,0x0,0x0,0x395f8,0x1d4c0},
182         {"Japan Envelope Chou #4 Rotated",0x1,0x320c8,0x15f90,0x0,0x0,0x320c8,0x15f90},
183         {"B6 (JIS)",0x1,0x1f400,0x2c6f0,0x0,0x0,0x1f400,0x2c6f0},
184         {"B6 (JIS) Rotated",0x1,0x2c6f0,0x1f400,0x0,0x0,0x2c6f0,0x1f400},
185         {"12x11",0x1,0x4a724,0x443e1,0x0,0x0,0x4a724,0x443e1},
186         {"Japan Envelope You #4",0x1,0x19a28,0x395f8,0x0,0x0,0x19a28,0x395f8},
187         {"Japan Envelope You #4 Rotated",0x1,0x395f8,0x19a28,0x0,0x0,0x395f8,0x19a28},
188         {"PRC 16K",0x1,0x2de60,0x3f7a0,0x0,0x0,0x2de60,0x3f7a0},
189         {"PRC 32K",0x1,0x1fbd0,0x2cec0,0x0,0x0,0x1fbd0,0x2cec0},
190         {"PRC 32K(Big)",0x1,0x222e0,0x318f8,0x0,0x0,0x222e0,0x318f8},
191         {"PRC Envelope #1",0x1,0x18e70,0x28488,0x0,0x0,0x18e70,0x28488},
192         {"PRC Envelope #2",0x1,0x18e70,0x2af80,0x0,0x0,0x18e70,0x2af80},
193         {"PRC Envelope #3",0x1,0x1e848,0x2af80,0x0,0x0,0x1e848,0x2af80},
194         {"PRC Envelope #4",0x1,0x1adb0,0x32c80,0x0,0x0,0x1adb0,0x32c80},
195         {"PRC Envelope #5",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
196         {"PRC Envelope #6",0x1,0x1d4c0,0x38270,0x0,0x0,0x1d4c0,0x38270},
197         {"PRC Envelope #7",0x1,0x27100,0x38270,0x0,0x0,0x27100,0x38270},
198         {"PRC Envelope #8",0x1,0x1d4c0,0x4b708,0x0,0x0,0x1d4c0,0x4b708},
199         {"PRC Envelope #9",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
200         {"PRC Envelope #10",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
201         {"PRC 16K Rotated",0x1,0x3f7a0,0x2de60,0x0,0x0,0x3f7a0,0x2de60},
202         {"PRC 32K Rotated",0x1,0x2cec0,0x1fbd0,0x0,0x0,0x2cec0,0x1fbd0},
203         {"PRC 32K(Big) Rotated",0x1,0x318f8,0x222e0,0x0,0x0,0x318f8,0x222e0},
204         {"PRC Envelope #1 Rotated",0x1,0x28488,0x18e70,0x0,0x0,0x28488,0x18e70},
205         {"PRC Envelope #2 Rotated",0x1,0x2af80,0x18e70,0x0,0x0,0x2af80,0x18e70},
206         {"PRC Envelope #3 Rotated",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
207         {"PRC Envelope #4 Rotated",0x1,0x32c80,0x1adb0,0x0,0x0,0x32c80,0x1adb0},
208         {"PRC Envelope #5 Rotated",0x1,0x35b60,0x1adb0,0x0,0x0,0x35b60,0x1adb0},
209         {"PRC Envelope #6 Rotated",0x1,0x38270,0x1d4c0,0x0,0x0,0x38270,0x1d4c0},
210         {"PRC Envelope #7 Rotated",0x1,0x38270,0x27100,0x0,0x0,0x38270,0x27100},
211         {"PRC Envelope #8 Rotated",0x1,0x4b708,0x1d4c0,0x0,0x0,0x4b708,0x1d4c0},
212         {"PRC Envelope #9 Rotated",0x1,0x4f1a0,0x37e88,0x0,0x0,0x4f1a0,0x37e88},
213         {"PRC Envelope #10 Rotated",0x1,0x6fd10,0x4f1a0,0x0,0x0,0x6fd10,0x4f1a0}
214 };
215
216 static const struct print_architecture_table_node archi_table[]= {
217
218         {"Windows 4.0",          SPL_ARCH_WIN40,        0 },
219         {"Windows NT x86",       SPL_ARCH_W32X86,       2 },
220         {"Windows NT R4000",     SPL_ARCH_W32MIPS,      2 },
221         {"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA,     2 },
222         {"Windows NT PowerPC",   SPL_ARCH_W32PPC,       2 },
223         {"Windows IA64",         SPL_ARCH_IA64,         3 },
224         {"Windows x64",          SPL_ARCH_X64,          3 },
225         {NULL,                   "",            -1 }
226 };
227
228
229 /****************************************************************************
230  generate a new TDB_DATA key for storing a printer
231 ****************************************************************************/
232
233 static TDB_DATA make_printer_tdbkey(TALLOC_CTX *ctx, const char *sharename )
234 {
235         fstring share;
236         char *keystr = NULL;
237         TDB_DATA key;
238
239         fstrcpy(share, sharename);
240         strlower_m(share);
241
242         keystr = talloc_asprintf(ctx, "%s%s", PRINTERS_PREFIX, share);
243         key = string_term_tdb_data(keystr ? keystr : "");
244
245         return key;
246 }
247
248 /****************************************************************************
249  generate a new TDB_DATA key for storing a printer security descriptor
250 ****************************************************************************/
251
252 static TDB_DATA make_printers_secdesc_tdbkey(TALLOC_CTX *ctx,
253                                         const char* sharename  )
254 {
255         fstring share;
256         char *keystr = NULL;
257         TDB_DATA key;
258
259         fstrcpy(share, sharename );
260         strlower_m(share);
261
262         keystr = talloc_asprintf(ctx, "%s%s", SECDESC_PREFIX, share);
263         key = string_term_tdb_data(keystr ? keystr : "");
264
265         return key;
266 }
267
268 /****************************************************************************
269 ****************************************************************************/
270
271 static bool upgrade_to_version_3(void)
272 {
273         TDB_DATA kbuf, newkey, dbuf;
274
275         DEBUG(0,("upgrade_to_version_3: upgrading print tdb's to version 3\n"));
276
277         for (kbuf = tdb_firstkey(tdb_drivers); kbuf.dptr;
278                         newkey = tdb_nextkey(tdb_drivers, kbuf), free(kbuf.dptr), kbuf=newkey) {
279
280                 dbuf = tdb_fetch(tdb_drivers, kbuf);
281
282                 if (strncmp((const char *)kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
283                         DEBUG(0,("upgrade_to_version_3:moving form\n"));
284                         if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) {
285                                 SAFE_FREE(dbuf.dptr);
286                                 DEBUG(0,("upgrade_to_version_3: failed to move form. Error (%s).\n", tdb_errorstr(tdb_forms)));
287                                 return False;
288                         }
289                         if (tdb_delete(tdb_drivers, kbuf) != 0) {
290                                 SAFE_FREE(dbuf.dptr);
291                                 DEBUG(0,("upgrade_to_version_3: failed to delete form. Error (%s)\n", tdb_errorstr(tdb_drivers)));
292                                 return False;
293                         }
294                 }
295
296                 if (strncmp((const char *)kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
297                         DEBUG(0,("upgrade_to_version_3:moving printer\n"));
298                         if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
299                                 SAFE_FREE(dbuf.dptr);
300                                 DEBUG(0,("upgrade_to_version_3: failed to move printer. Error (%s)\n", tdb_errorstr(tdb_printers)));
301                                 return False;
302                         }
303                         if (tdb_delete(tdb_drivers, kbuf) != 0) {
304                                 SAFE_FREE(dbuf.dptr);
305                                 DEBUG(0,("upgrade_to_version_3: failed to delete printer. Error (%s)\n", tdb_errorstr(tdb_drivers)));
306                                 return False;
307                         }
308                 }
309
310                 if (strncmp((const char *)kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
311                         DEBUG(0,("upgrade_to_version_3:moving secdesc\n"));
312                         if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
313                                 SAFE_FREE(dbuf.dptr);
314                                 DEBUG(0,("upgrade_to_version_3: failed to move secdesc. Error (%s)\n", tdb_errorstr(tdb_printers)));
315                                 return False;
316                         }
317                         if (tdb_delete(tdb_drivers, kbuf) != 0) {
318                                 SAFE_FREE(dbuf.dptr);
319                                 DEBUG(0,("upgrade_to_version_3: failed to delete secdesc. Error (%s)\n", tdb_errorstr(tdb_drivers)));
320                                 return False;
321                         }
322                 }
323
324                 SAFE_FREE(dbuf.dptr);
325         }
326
327         return True;
328 }
329
330 /*******************************************************************
331  Fix an issue with security descriptors.  Printer sec_desc must
332  use more than the generic bits that were previously used
333  in <= 3.0.14a.  They must also have a owner and group SID assigned.
334  Otherwise, any printers than have been migrated to a Windows
335  host using printmig.exe will not be accessible.
336 *******************************************************************/
337
338 static int sec_desc_upg_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
339                             TDB_DATA data, void *state )
340 {
341         NTSTATUS status;
342         struct sec_desc_buf *sd_orig = NULL;
343         struct sec_desc_buf *sd_new, *sd_store;
344         struct security_descriptor *sec, *new_sec;
345         TALLOC_CTX *ctx = state;
346         int result, i;
347         uint32 sd_size;
348         size_t size_new_sec;
349
350         if (!data.dptr || data.dsize == 0) {
351                 return 0;
352         }
353
354         if ( strncmp((const char *) key.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX) ) != 0 ) {
355                 return 0;
356         }
357
358         /* upgrade the security descriptor */
359
360         status = unmarshall_sec_desc_buf(ctx, data.dptr, data.dsize, &sd_orig);
361         if (!NT_STATUS_IS_OK(status)) {
362                 /* delete bad entries */
363                 DEBUG(0,("sec_desc_upg_fn: Failed to parse original sec_desc for %si.  Deleting....\n",
364                         (const char *)key.dptr ));
365                 tdb_delete( tdb_printers, key );
366                 return 0;
367         }
368
369         if (!sd_orig) {
370                 return 0;
371         }
372         sec = sd_orig->sd;
373
374         /* is this even valid? */
375
376         if ( !sec->dacl ) {
377                 return 0;
378         }
379
380         /* update access masks */
381
382         for ( i=0; i<sec->dacl->num_aces; i++ ) {
383                 switch ( sec->dacl->aces[i].access_mask ) {
384                         case (GENERIC_READ_ACCESS | GENERIC_WRITE_ACCESS | GENERIC_EXECUTE_ACCESS):
385                                 sec->dacl->aces[i].access_mask = PRINTER_ACE_PRINT;
386                                 break;
387
388                         case GENERIC_ALL_ACCESS:
389                                 sec->dacl->aces[i].access_mask = PRINTER_ACE_FULL_CONTROL;
390                                 break;
391
392                         case READ_CONTROL_ACCESS:
393                                 sec->dacl->aces[i].access_mask = PRINTER_ACE_MANAGE_DOCUMENTS;
394
395                         default:        /* no change */
396                                 break;
397                 }
398         }
399
400         /* create a new struct security_descriptor with the appropriate owner and group SIDs */
401
402         new_sec = make_sec_desc( ctx, SD_REVISION, SEC_DESC_SELF_RELATIVE,
403                                  &global_sid_Builtin_Administrators,
404                                  &global_sid_Builtin_Administrators,
405                                  NULL, NULL, &size_new_sec );
406         if (!new_sec) {
407                 return 0;
408         }
409         sd_new = make_sec_desc_buf( ctx, size_new_sec, new_sec );
410         if (!sd_new) {
411                 return 0;
412         }
413
414         if ( !(sd_store = sec_desc_merge_buf( ctx, sd_new, sd_orig )) ) {
415                 DEBUG(0,("sec_desc_upg_fn: Failed to update sec_desc for %s\n", key.dptr ));
416                 return 0;
417         }
418
419         /* store it back */
420
421         sd_size = ndr_size_security_descriptor(sd_store->sd, 0)
422                 + sizeof(struct sec_desc_buf);
423
424         status = marshall_sec_desc_buf(ctx, sd_store, &data.dptr, &data.dsize);
425         if (!NT_STATUS_IS_OK(status)) {
426                 DEBUG(0,("sec_desc_upg_fn: Failed to parse new sec_desc for %s\n", key.dptr ));
427                 return 0;
428         }
429
430         result = tdb_store( tdb_printers, key, data, TDB_REPLACE );
431
432         /* 0 to continue and non-zero to stop traversal */
433
434         return (result == -1);
435 }
436
437 /*******************************************************************
438 *******************************************************************/
439
440 static bool upgrade_to_version_4(void)
441 {
442         TALLOC_CTX *ctx;
443         int result;
444
445         DEBUG(0,("upgrade_to_version_4: upgrading printer security descriptors\n"));
446
447         if ( !(ctx = talloc_init( "upgrade_to_version_4" )) )
448                 return False;
449
450         result = tdb_traverse( tdb_printers, sec_desc_upg_fn, ctx );
451
452         talloc_destroy( ctx );
453
454         return ( result != -1 );
455 }
456
457 /*******************************************************************
458  Fix an issue with security descriptors.  Printer sec_desc must
459  use more than the generic bits that were previously used
460  in <= 3.0.14a.  They must also have a owner and group SID assigned.
461  Otherwise, any printers than have been migrated to a Windows
462  host using printmig.exe will not be accessible.
463 *******************************************************************/
464
465 static int normalize_printers_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
466                                   TDB_DATA data, void *state )
467 {
468         TALLOC_CTX *ctx = talloc_tos();
469         TDB_DATA new_key;
470
471         if (!data.dptr || data.dsize == 0)
472                 return 0;
473
474         /* upgrade printer records and security descriptors */
475
476         if ( strncmp((const char *) key.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX) ) == 0 ) {
477                 new_key = make_printer_tdbkey(ctx, (const char *)key.dptr+strlen(PRINTERS_PREFIX) );
478         }
479         else if ( strncmp((const char *) key.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX) ) == 0 ) {
480                 new_key = make_printers_secdesc_tdbkey(ctx, (const char *)key.dptr+strlen(SECDESC_PREFIX) );
481         }
482         else {
483                 /* ignore this record */
484                 return 0;
485         }
486
487         /* delete the original record and store under the normalized key */
488
489         if ( tdb_delete( the_tdb, key ) != 0 ) {
490                 DEBUG(0,("normalize_printers_fn: tdb_delete for [%s] failed!\n",
491                         key.dptr));
492                 return 1;
493         }
494
495         if ( tdb_store( the_tdb, new_key, data, TDB_REPLACE) != 0 ) {
496                 DEBUG(0,("normalize_printers_fn: failed to store new record for [%s]!\n",
497                         key.dptr));
498                 return 1;
499         }
500
501         return 0;
502 }
503
504 /*******************************************************************
505 *******************************************************************/
506
507 static bool upgrade_to_version_5(void)
508 {
509         TALLOC_CTX *ctx;
510         int result;
511
512         DEBUG(0,("upgrade_to_version_5: normalizing printer keys\n"));
513
514         if ( !(ctx = talloc_init( "upgrade_to_version_5" )) )
515                 return False;
516
517         result = tdb_traverse( tdb_printers, normalize_printers_fn, NULL );
518
519         talloc_destroy( ctx );
520
521         return ( result != -1 );
522 }
523
524 /****************************************************************************
525  Open the NT printing tdbs. Done once before fork().
526 ****************************************************************************/
527
528 bool nt_printing_init(struct messaging_context *msg_ctx)
529 {
530         const char *vstring = "INFO/version";
531         WERROR win_rc;
532         int32 vers_id;
533
534         if ( tdb_drivers && tdb_printers && tdb_forms )
535                 return True;
536
537         if (tdb_drivers)
538                 tdb_close(tdb_drivers);
539         tdb_drivers = tdb_open_log(state_path("ntdrivers.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
540         if (!tdb_drivers) {
541                 DEBUG(0,("nt_printing_init: Failed to open nt drivers database %s (%s)\n",
542                         state_path("ntdrivers.tdb"), strerror(errno) ));
543                 return False;
544         }
545
546         if (tdb_printers)
547                 tdb_close(tdb_printers);
548         tdb_printers = tdb_open_log(state_path("ntprinters.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
549         if (!tdb_printers) {
550                 DEBUG(0,("nt_printing_init: Failed to open nt printers database %s (%s)\n",
551                         state_path("ntprinters.tdb"), strerror(errno) ));
552                 return False;
553         }
554
555         if (tdb_forms)
556                 tdb_close(tdb_forms);
557         tdb_forms = tdb_open_log(state_path("ntforms.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
558         if (!tdb_forms) {
559                 DEBUG(0,("nt_printing_init: Failed to open nt forms database %s (%s)\n",
560                         state_path("ntforms.tdb"), strerror(errno) ));
561                 return False;
562         }
563
564         /* handle a Samba upgrade */
565
566         vers_id = tdb_fetch_int32(tdb_drivers, vstring);
567         if (vers_id == -1) {
568                 DEBUG(10, ("Fresh database\n"));
569                 tdb_store_int32( tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_5 );
570                 vers_id = NTDRIVERS_DATABASE_VERSION_5;
571         }
572
573         if ( vers_id != NTDRIVERS_DATABASE_VERSION_5 ) {
574
575                 if ((vers_id == NTDRIVERS_DATABASE_VERSION_1) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_1)) {
576                         if (!upgrade_to_version_3())
577                                 return False;
578                         tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_3);
579                         vers_id = NTDRIVERS_DATABASE_VERSION_3;
580                 }
581
582                 if ((vers_id == NTDRIVERS_DATABASE_VERSION_2) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_2)) {
583                         /* Written on a bigendian machine with old fetch_int code. Save as le. */
584                         /* The only upgrade between V2 and V3 is to save the version in little-endian. */
585                         tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_3);
586                         vers_id = NTDRIVERS_DATABASE_VERSION_3;
587                 }
588
589                 if (vers_id == NTDRIVERS_DATABASE_VERSION_3 ) {
590                         if ( !upgrade_to_version_4() )
591                                 return False;
592                         tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_4);
593                         vers_id = NTDRIVERS_DATABASE_VERSION_4;
594                 }
595
596                 if (vers_id == NTDRIVERS_DATABASE_VERSION_4 ) {
597                         if ( !upgrade_to_version_5() )
598                                 return False;
599                         tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_5);
600                         vers_id = NTDRIVERS_DATABASE_VERSION_5;
601                 }
602
603
604                 if ( vers_id != NTDRIVERS_DATABASE_VERSION_5 ) {
605                         DEBUG(0,("nt_printing_init: Unknown printer database version [%d]\n", vers_id));
606                         return False;
607                 }
608         }
609
610         /*
611          * register callback to handle updating printers as new
612          * drivers are installed
613          */
614
615         messaging_register(msg_ctx, NULL, MSG_PRINTER_DRVUPGRADE,
616                            do_drv_upgrade_printer);
617
618         /* of course, none of the message callbacks matter if you don't
619            tell messages.c that you interested in receiving PRINT_GENERAL
620            msgs.  This is done in serverid_register() */
621
622
623         if ( lp_security() == SEC_ADS ) {
624                 win_rc = check_published_printers();
625                 if (!W_ERROR_IS_OK(win_rc))
626                         DEBUG(0, ("nt_printing_init: error checking published printers: %s\n", win_errstr(win_rc)));
627         }
628
629         return True;
630 }
631
632 /*******************************************************************
633  Function to allow filename parsing "the old way".
634 ********************************************************************/
635
636 static NTSTATUS driver_unix_convert(connection_struct *conn,
637                                     const char *old_name,
638                                     struct smb_filename **smb_fname)
639 {
640         NTSTATUS status;
641         TALLOC_CTX *ctx = talloc_tos();
642         char *name = talloc_strdup(ctx, old_name);
643
644         if (!name) {
645                 return NT_STATUS_NO_MEMORY;
646         }
647         unix_format(name);
648         name = unix_clean_name(ctx, name);
649         if (!name) {
650                 return NT_STATUS_NO_MEMORY;
651         }
652         trim_string(name,"/","/");
653
654         status = unix_convert(ctx, conn, name, smb_fname, 0);
655         if (!NT_STATUS_IS_OK(status)) {
656                 return NT_STATUS_NO_MEMORY;
657         }
658
659         return NT_STATUS_OK;
660 }
661
662 /*******************************************************************
663  tdb traversal function for counting printers.
664 ********************************************************************/
665
666 static int traverse_counting_printers(TDB_CONTEXT *t, TDB_DATA key,
667                                       TDB_DATA data, void *context)
668 {
669         int *printer_count = (int*)context;
670
671         if (memcmp(PRINTERS_PREFIX, key.dptr, sizeof(PRINTERS_PREFIX)-1) == 0) {
672                 (*printer_count)++;
673                 DEBUG(10,("traverse_counting_printers: printer = [%s]  printer_count = %d\n", key.dptr, *printer_count));
674         }
675
676         return 0;
677 }
678
679 /*******************************************************************
680  Update the spooler global c_setprinter. This variable is initialized
681  when the parent smbd starts with the number of existing printers. It
682  is monotonically increased by the current number of printers *after*
683  each add or delete printer RPC. Only Microsoft knows why... JRR020119
684 ********************************************************************/
685
686 uint32 update_c_setprinter(bool initialize)
687 {
688         int32 c_setprinter;
689         int32 printer_count = 0;
690
691         tdb_lock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);
692
693         /* Traverse the tdb, counting the printers */
694         tdb_traverse(tdb_printers, traverse_counting_printers, (void *)&printer_count);
695
696         /* If initializing, set c_setprinter to current printers count
697          * otherwise, bump it by the current printer count
698          */
699         if (!initialize)
700                 c_setprinter = tdb_fetch_int32(tdb_printers, GLOBAL_C_SETPRINTER) + printer_count;
701         else
702                 c_setprinter = printer_count;
703
704         DEBUG(10,("update_c_setprinter: c_setprinter = %u\n", (unsigned int)c_setprinter));
705         tdb_store_int32(tdb_printers, GLOBAL_C_SETPRINTER, c_setprinter);
706
707         tdb_unlock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);
708
709         return (uint32)c_setprinter;
710 }
711
712 /*******************************************************************
713  Get the spooler global c_setprinter, accounting for initialization.
714 ********************************************************************/
715
716 uint32 get_c_setprinter(void)
717 {
718         int32 c_setprinter = tdb_fetch_int32(tdb_printers, GLOBAL_C_SETPRINTER);
719
720         if (c_setprinter == (int32)-1)
721                 c_setprinter = update_c_setprinter(True);
722
723         DEBUG(10,("get_c_setprinter: c_setprinter = %d\n", c_setprinter));
724
725         return (uint32)c_setprinter;
726 }
727
728 /****************************************************************************
729  Get builtin form struct list.
730 ****************************************************************************/
731
732 int get_builtin_ntforms(nt_forms_struct **list)
733 {
734         *list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));
735         if (!*list) {
736                 return 0;
737         }
738         return ARRAY_SIZE(default_forms);
739 }
740
741 /****************************************************************************
742  get a builtin form struct
743 ****************************************************************************/
744
745 bool get_a_builtin_ntform_by_string(const char *form_name, nt_forms_struct *form)
746 {
747         int i;
748         DEBUGADD(6,("Looking for builtin form %s \n", form_name));
749         for (i=0; i<ARRAY_SIZE(default_forms); i++) {
750                 if (strequal(form_name,default_forms[i].name)) {
751                         DEBUGADD(6,("Found builtin form %s \n", form_name));
752                         memcpy(form,&default_forms[i],sizeof(*form));
753                         return true;
754                 }
755         }
756
757         return false;
758 }
759
760 /****************************************************************************
761  get a form struct list.
762 ****************************************************************************/
763
764 int get_ntforms(nt_forms_struct **list)
765 {
766         TDB_DATA kbuf, newkey, dbuf;
767         nt_forms_struct form;
768         int ret;
769         int i;
770         int n = 0;
771
772         *list = NULL;
773
774         for (kbuf = tdb_firstkey(tdb_forms);
775              kbuf.dptr;
776              newkey = tdb_nextkey(tdb_forms, kbuf), free(kbuf.dptr), kbuf=newkey)
777         {
778                 if (strncmp((const char *)kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0)
779                         continue;
780
781                 dbuf = tdb_fetch(tdb_forms, kbuf);
782                 if (!dbuf.dptr)
783                         continue;
784
785                 fstrcpy(form.name, (const char *)kbuf.dptr+strlen(FORMS_PREFIX));
786                 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddd",
787                                  &i, &form.flag, &form.width, &form.length, &form.left,
788                                  &form.top, &form.right, &form.bottom);
789                 SAFE_FREE(dbuf.dptr);
790                 if (ret != dbuf.dsize)
791                         continue;
792
793                 *list = SMB_REALLOC_ARRAY(*list, nt_forms_struct, n+1);
794                 if (!*list) {
795                         DEBUG(0,("get_ntforms: Realloc fail.\n"));
796                         return 0;
797                 }
798                 (*list)[n] = form;
799                 n++;
800         }
801
802
803         return n;
804 }
805
806 /****************************************************************************
807 write a form struct list
808 ****************************************************************************/
809
810 int write_ntforms(nt_forms_struct **list, int number)
811 {
812         TALLOC_CTX *ctx = talloc_tos();
813         char *buf = NULL;
814         char *key = NULL;
815         int len;
816         TDB_DATA dbuf;
817         int i;
818
819         for (i=0;i<number;i++) {
820                 /* save index, so list is rebuilt in correct order */
821                 len = tdb_pack(NULL, 0, "dddddddd",
822                                i, (*list)[i].flag, (*list)[i].width, (*list)[i].length,
823                                (*list)[i].left, (*list)[i].top, (*list)[i].right,
824                                (*list)[i].bottom);
825                 if (!len) {
826                         continue;
827                 }
828                 buf = TALLOC_ARRAY(ctx, char, len);
829                 if (!buf) {
830                         return 0;
831                 }
832                 len = tdb_pack((uint8 *)buf, len, "dddddddd",
833                                i, (*list)[i].flag, (*list)[i].width, (*list)[i].length,
834                                (*list)[i].left, (*list)[i].top, (*list)[i].right,
835                                (*list)[i].bottom);
836                 key = talloc_asprintf(ctx, "%s%s", FORMS_PREFIX, (*list)[i].name);
837                 if (!key) {
838                         return 0;
839                 }
840                 dbuf.dsize = len;
841                 dbuf.dptr = (uint8 *)buf;
842                 if (tdb_store_bystring(tdb_forms, key, dbuf, TDB_REPLACE) != 0) {
843                         TALLOC_FREE(key);
844                         TALLOC_FREE(buf);
845                         break;
846                 }
847                 TALLOC_FREE(key);
848                 TALLOC_FREE(buf);
849        }
850
851        return i;
852 }
853
854 /****************************************************************************
855 add a form struct at the end of the list
856 ****************************************************************************/
857 bool add_a_form(nt_forms_struct **list, struct spoolss_AddFormInfo1 *form, int *count)
858 {
859         int n=0;
860         bool update;
861
862         /*
863          * NT tries to add forms even when
864          * they are already in the base
865          * only update the values if already present
866          */
867
868         update=False;
869
870         for (n=0; n<*count; n++) {
871                 if ( strequal((*list)[n].name, form->form_name) ) {
872                         update=True;
873                         break;
874                 }
875         }
876
877         if (update==False) {
878                 if((*list=SMB_REALLOC_ARRAY(*list, nt_forms_struct, n+1)) == NULL) {
879                         DEBUG(0,("add_a_form: failed to enlarge forms list!\n"));
880                         return False;
881                 }
882                 fstrcpy((*list)[n].name, form->form_name);
883                 (*count)++;
884         }
885
886         (*list)[n].flag         = form->flags;
887         (*list)[n].width        = form->size.width;
888         (*list)[n].length       = form->size.height;
889         (*list)[n].left         = form->area.left;
890         (*list)[n].top          = form->area.top;
891         (*list)[n].right        = form->area.right;
892         (*list)[n].bottom       = form->area.bottom;
893
894         DEBUG(6,("add_a_form: Successfully %s form [%s]\n",
895                 update ? "updated" : "added", form->form_name));
896
897         return True;
898 }
899
900 /****************************************************************************
901  Delete a named form struct.
902 ****************************************************************************/
903
904 bool delete_a_form(nt_forms_struct **list, const char *del_name, int *count, WERROR *ret)
905 {
906         char *key = NULL;
907         int n=0;
908
909         *ret = WERR_OK;
910
911         for (n=0; n<*count; n++) {
912                 if (!strncmp((*list)[n].name, del_name, strlen(del_name))) {
913                         DEBUG(103, ("delete_a_form, [%s] in list\n", del_name));
914                         break;
915                 }
916         }
917
918         if (n == *count) {
919                 DEBUG(10,("delete_a_form, [%s] not found\n", del_name));
920                 *ret = WERR_INVALID_FORM_NAME;
921                 return False;
922         }
923
924         if (asprintf(&key, "%s%s", FORMS_PREFIX, (*list)[n].name) < 0) {
925                 *ret = WERR_NOMEM;
926                 return false;
927         }
928         if (tdb_delete_bystring(tdb_forms, key) != 0) {
929                 SAFE_FREE(key);
930                 *ret = WERR_NOMEM;
931                 return False;
932         }
933         SAFE_FREE(key);
934         return true;
935 }
936
937 /****************************************************************************
938  Update a form struct.
939 ****************************************************************************/
940
941 void update_a_form(nt_forms_struct **list, struct spoolss_AddFormInfo1 *form, int count)
942 {
943         int n=0;
944
945         DEBUG(106, ("[%s]\n", form->form_name));
946         for (n=0; n<count; n++) {
947                 DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
948                 if (!strncmp((*list)[n].name, form->form_name, strlen(form->form_name)))
949                         break;
950         }
951
952         if (n==count) return;
953
954         (*list)[n].flag         = form->flags;
955         (*list)[n].width        = form->size.width;
956         (*list)[n].length       = form->size.height;
957         (*list)[n].left         = form->area.left;
958         (*list)[n].top          = form->area.top;
959         (*list)[n].right        = form->area.right;
960         (*list)[n].bottom       = form->area.bottom;
961 }
962
963 /****************************************************************************
964  Function to do the mapping between the long architecture name and
965  the short one.
966 ****************************************************************************/
967
968 const char *get_short_archi(const char *long_archi)
969 {
970         int i=-1;
971
972         DEBUG(107,("Getting architecture dependant directory\n"));
973         do {
974                 i++;
975         } while ( (archi_table[i].long_archi!=NULL ) &&
976                   StrCaseCmp(long_archi, archi_table[i].long_archi) );
977
978         if (archi_table[i].long_archi==NULL) {
979                 DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi));
980                 return NULL;
981         }
982
983         /* this might be client code - but shouldn't this be an fstrcpy etc? */
984
985         DEBUGADD(108,("index: [%d]\n", i));
986         DEBUGADD(108,("long architecture: [%s]\n", archi_table[i].long_archi));
987         DEBUGADD(108,("short architecture: [%s]\n", archi_table[i].short_archi));
988
989         return archi_table[i].short_archi;
990 }
991
992 /****************************************************************************
993  Version information in Microsoft files is held in a VS_VERSION_INFO structure.
994  There are two case to be covered here: PE (Portable Executable) and NE (New
995  Executable) files. Both files support the same INFO structure, but PE files
996  store the signature in unicode, and NE files store it as !unicode.
997  returns -1 on error, 1 on version info found, and 0 on no version info found.
998 ****************************************************************************/
999
1000 static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 *minor)
1001 {
1002         int     i;
1003         char    *buf = NULL;
1004         ssize_t byte_count;
1005
1006         if ((buf=(char *)SMB_MALLOC(DOS_HEADER_SIZE)) == NULL) {
1007                 DEBUG(0,("get_file_version: PE file [%s] DOS Header malloc failed bytes = %d\n",
1008                                 fname, DOS_HEADER_SIZE));
1009                 goto error_exit;
1010         }
1011
1012         if ((byte_count = vfs_read_data(fsp, buf, DOS_HEADER_SIZE)) < DOS_HEADER_SIZE) {
1013                 DEBUG(3,("get_file_version: File [%s] DOS header too short, bytes read = %lu\n",
1014                          fname, (unsigned long)byte_count));
1015                 goto no_version_info;
1016         }
1017
1018         /* Is this really a DOS header? */
1019         if (SVAL(buf,DOS_HEADER_MAGIC_OFFSET) != DOS_HEADER_MAGIC) {
1020                 DEBUG(6,("get_file_version: File [%s] bad DOS magic = 0x%x\n",
1021                                 fname, SVAL(buf,DOS_HEADER_MAGIC_OFFSET)));
1022                 goto no_version_info;
1023         }
1024
1025         /* Skip OEM header (if any) and the DOS stub to start of Windows header */
1026         if (SMB_VFS_LSEEK(fsp, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
1027                 DEBUG(3,("get_file_version: File [%s] too short, errno = %d\n",
1028                                 fname, errno));
1029                 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
1030                 goto no_version_info;
1031         }
1032
1033         /* Note: DOS_HEADER_SIZE and NE_HEADER_SIZE are incidentally same */
1034         if ((byte_count = vfs_read_data(fsp, buf, NE_HEADER_SIZE)) < NE_HEADER_SIZE) {
1035                 DEBUG(3,("get_file_version: File [%s] Windows header too short, bytes read = %lu\n",
1036                          fname, (unsigned long)byte_count));
1037                 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
1038                 goto no_version_info;
1039         }
1040
1041         /* The header may be a PE (Portable Executable) or an NE (New Executable) */
1042         if (IVAL(buf,PE_HEADER_SIGNATURE_OFFSET) == PE_HEADER_SIGNATURE) {
1043                 unsigned int num_sections;
1044                 unsigned int section_table_bytes;
1045
1046                 /* Just skip over optional header to get to section table */
1047                 if (SMB_VFS_LSEEK(fsp,
1048                                 SVAL(buf,PE_HEADER_OPTIONAL_HEADER_SIZE)-(NE_HEADER_SIZE-PE_HEADER_SIZE),
1049                                 SEEK_CUR) == (SMB_OFF_T)-1) {
1050                         DEBUG(3,("get_file_version: File [%s] Windows optional header too short, errno = %d\n",
1051                                 fname, errno));
1052                         goto error_exit;
1053                 }
1054
1055                 /* get the section table */
1056                 num_sections        = SVAL(buf,PE_HEADER_NUMBER_OF_SECTIONS);
1057                 section_table_bytes = num_sections * PE_HEADER_SECT_HEADER_SIZE;
1058                 if (section_table_bytes == 0)
1059                         goto error_exit;
1060
1061                 SAFE_FREE(buf);
1062                 if ((buf=(char *)SMB_MALLOC(section_table_bytes)) == NULL) {
1063                         DEBUG(0,("get_file_version: PE file [%s] section table malloc failed bytes = %d\n",
1064                                         fname, section_table_bytes));
1065                         goto error_exit;
1066                 }
1067
1068                 if ((byte_count = vfs_read_data(fsp, buf, section_table_bytes)) < section_table_bytes) {
1069                         DEBUG(3,("get_file_version: PE file [%s] Section header too short, bytes read = %lu\n",
1070                                  fname, (unsigned long)byte_count));
1071                         goto error_exit;
1072                 }
1073
1074                 /* Iterate the section table looking for the resource section ".rsrc" */
1075                 for (i = 0; i < num_sections; i++) {
1076                         int sec_offset = i * PE_HEADER_SECT_HEADER_SIZE;
1077
1078                         if (strcmp(".rsrc", &buf[sec_offset+PE_HEADER_SECT_NAME_OFFSET]) == 0) {
1079                                 unsigned int section_pos   = IVAL(buf,sec_offset+PE_HEADER_SECT_PTR_DATA_OFFSET);
1080                                 unsigned int section_bytes = IVAL(buf,sec_offset+PE_HEADER_SECT_SIZE_DATA_OFFSET);
1081
1082                                 if (section_bytes == 0)
1083                                         goto error_exit;
1084
1085                                 SAFE_FREE(buf);
1086                                 if ((buf=(char *)SMB_MALLOC(section_bytes)) == NULL) {
1087                                         DEBUG(0,("get_file_version: PE file [%s] version malloc failed bytes = %d\n",
1088                                                         fname, section_bytes));
1089                                         goto error_exit;
1090                                 }
1091
1092                                 /* Seek to the start of the .rsrc section info */
1093                                 if (SMB_VFS_LSEEK(fsp, section_pos, SEEK_SET) == (SMB_OFF_T)-1) {
1094                                         DEBUG(3,("get_file_version: PE file [%s] too short for section info, errno = %d\n",
1095                                                         fname, errno));
1096                                         goto error_exit;
1097                                 }
1098
1099                                 if ((byte_count = vfs_read_data(fsp, buf, section_bytes)) < section_bytes) {
1100                                         DEBUG(3,("get_file_version: PE file [%s] .rsrc section too short, bytes read = %lu\n",
1101                                                  fname, (unsigned long)byte_count));
1102                                         goto error_exit;
1103                                 }
1104
1105                                 if (section_bytes < VS_VERSION_INFO_UNICODE_SIZE)
1106                                         goto error_exit;
1107
1108                                 for (i=0; i<section_bytes-VS_VERSION_INFO_UNICODE_SIZE; i++) {
1109                                         /* Scan for 1st 3 unicoded bytes followed by word aligned magic value */
1110                                         if (buf[i] == 'V' && buf[i+1] == '\0' && buf[i+2] == 'S') {
1111                                                 /* Align to next long address */
1112                                                 int pos = (i + sizeof(VS_SIGNATURE)*2 + 3) & 0xfffffffc;
1113
1114                                                 if (IVAL(buf,pos) == VS_MAGIC_VALUE) {
1115                                                         *major = IVAL(buf,pos+VS_MAJOR_OFFSET);
1116                                                         *minor = IVAL(buf,pos+VS_MINOR_OFFSET);
1117
1118                                                         DEBUG(6,("get_file_version: PE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
1119                                                                           fname, *major, *minor,
1120                                                                           (*major>>16)&0xffff, *major&0xffff,
1121                                                                           (*minor>>16)&0xffff, *minor&0xffff));
1122                                                         SAFE_FREE(buf);
1123                                                         return 1;
1124                                                 }
1125                                         }
1126                                 }
1127                         }
1128                 }
1129
1130                 /* Version info not found, fall back to origin date/time */
1131                 DEBUG(10,("get_file_version: PE file [%s] has no version info\n", fname));
1132                 SAFE_FREE(buf);
1133                 return 0;
1134
1135         } else if (SVAL(buf,NE_HEADER_SIGNATURE_OFFSET) == NE_HEADER_SIGNATURE) {
1136                 if (CVAL(buf,NE_HEADER_TARGET_OS_OFFSET) != NE_HEADER_TARGOS_WIN ) {
1137                         DEBUG(3,("get_file_version: NE file [%s] wrong target OS = 0x%x\n",
1138                                         fname, CVAL(buf,NE_HEADER_TARGET_OS_OFFSET)));
1139                         /* At this point, we assume the file is in error. It still could be somthing
1140                          * else besides a NE file, but it unlikely at this point. */
1141                         goto error_exit;
1142                 }
1143
1144                 /* Allocate a bit more space to speed up things */
1145                 SAFE_FREE(buf);
1146                 if ((buf=(char *)SMB_MALLOC(VS_NE_BUF_SIZE)) == NULL) {
1147                         DEBUG(0,("get_file_version: NE file [%s] malloc failed bytes  = %d\n",
1148                                         fname, PE_HEADER_SIZE));
1149                         goto error_exit;
1150                 }
1151
1152                 /* This is a HACK! I got tired of trying to sort through the messy
1153                  * 'NE' file format. If anyone wants to clean this up please have at
1154                  * it, but this works. 'NE' files will eventually fade away. JRR */
1155                 while((byte_count = vfs_read_data(fsp, buf, VS_NE_BUF_SIZE)) > 0) {
1156                         /* Cover case that should not occur in a well formed 'NE' .dll file */
1157                         if (byte_count-VS_VERSION_INFO_SIZE <= 0) break;
1158
1159                         for(i=0; i<byte_count; i++) {
1160                                 /* Fast skip past data that can't possibly match */
1161                                 if (buf[i] != 'V') continue;
1162
1163                                 /* Potential match data crosses buf boundry, move it to beginning
1164                                  * of buf, and fill the buf with as much as it will hold. */
1165                                 if (i>byte_count-VS_VERSION_INFO_SIZE) {
1166                                         int bc;
1167
1168                                         memcpy(buf, &buf[i], byte_count-i);
1169                                         if ((bc = vfs_read_data(fsp, &buf[byte_count-i], VS_NE_BUF_SIZE-
1170                                                                    (byte_count-i))) < 0) {
1171
1172                                                 DEBUG(0,("get_file_version: NE file [%s] Read error, errno=%d\n",
1173                                                                  fname, errno));
1174                                                 goto error_exit;
1175                                         }
1176
1177                                         byte_count = bc + (byte_count - i);
1178                                         if (byte_count<VS_VERSION_INFO_SIZE) break;
1179
1180                                         i = 0;
1181                                 }
1182
1183                                 /* Check that the full signature string and the magic number that
1184                                  * follows exist (not a perfect solution, but the chances that this
1185                                  * occurs in code is, well, remote. Yes I know I'm comparing the 'V'
1186                                  * twice, as it is simpler to read the code. */
1187                                 if (strcmp(&buf[i], VS_SIGNATURE) == 0) {
1188                                         /* Compute skip alignment to next long address */
1189                                         int skip = -(SMB_VFS_LSEEK(fsp, 0, SEEK_CUR) - (byte_count - i) +
1190                                                                  sizeof(VS_SIGNATURE)) & 3;
1191                                         if (IVAL(buf,i+sizeof(VS_SIGNATURE)+skip) != 0xfeef04bd) continue;
1192
1193                                         *major = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MAJOR_OFFSET);
1194                                         *minor = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MINOR_OFFSET);
1195                                         DEBUG(6,("get_file_version: NE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
1196                                                           fname, *major, *minor,
1197                                                           (*major>>16)&0xffff, *major&0xffff,
1198                                                           (*minor>>16)&0xffff, *minor&0xffff));
1199                                         SAFE_FREE(buf);
1200                                         return 1;
1201                                 }
1202                         }
1203                 }
1204
1205                 /* Version info not found, fall back to origin date/time */
1206                 DEBUG(0,("get_file_version: NE file [%s] Version info not found\n", fname));
1207                 SAFE_FREE(buf);
1208                 return 0;
1209
1210         } else
1211                 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
1212                 DEBUG(3,("get_file_version: File [%s] unknown file format, signature = 0x%x\n",
1213                                 fname, IVAL(buf,PE_HEADER_SIGNATURE_OFFSET)));
1214
1215         no_version_info:
1216                 SAFE_FREE(buf);
1217                 return 0;
1218
1219         error_exit:
1220                 SAFE_FREE(buf);
1221                 return -1;
1222 }
1223
1224 /****************************************************************************
1225 Drivers for Microsoft systems contain multiple files. Often, multiple drivers
1226 share one or more files. During the MS installation process files are checked
1227 to insure that only a newer version of a shared file is installed over an
1228 older version. There are several possibilities for this comparison. If there
1229 is no previous version, the new one is newer (obviously). If either file is
1230 missing the version info structure, compare the creation date (on Unix use
1231 the modification date). Otherwise chose the numerically larger version number.
1232 ****************************************************************************/
1233
1234 static int file_version_is_newer(connection_struct *conn, fstring new_file, fstring old_file)
1235 {
1236         bool use_version = true;
1237
1238         uint32 new_major;
1239         uint32 new_minor;
1240         time_t new_create_time;
1241
1242         uint32 old_major;
1243         uint32 old_minor;
1244         time_t old_create_time;
1245
1246         struct smb_filename *smb_fname = NULL;
1247         files_struct    *fsp = NULL;
1248         SMB_STRUCT_STAT st;
1249
1250         NTSTATUS status;
1251         int ret;
1252
1253         SET_STAT_INVALID(st);
1254         new_create_time = (time_t)0;
1255         old_create_time = (time_t)0;
1256
1257         /* Get file version info (if available) for previous file (if it exists) */
1258         status = driver_unix_convert(conn, old_file, &smb_fname);
1259         if (!NT_STATUS_IS_OK(status)) {
1260                 goto error_exit;
1261         }
1262
1263         status = SMB_VFS_CREATE_FILE(
1264                 conn,                                   /* conn */
1265                 NULL,                                   /* req */
1266                 0,                                      /* root_dir_fid */
1267                 smb_fname,                              /* fname */
1268                 FILE_GENERIC_READ,                      /* access_mask */
1269                 FILE_SHARE_READ | FILE_SHARE_WRITE,     /* share_access */
1270                 FILE_OPEN,                              /* create_disposition*/
1271                 0,                                      /* create_options */
1272                 FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
1273                 INTERNAL_OPEN_ONLY,                     /* oplock_request */
1274                 0,                                      /* allocation_size */
1275                 0,                                      /* private_flags */
1276                 NULL,                                   /* sd */
1277                 NULL,                                   /* ea_list */
1278                 &fsp,                                   /* result */
1279                 NULL);                                  /* pinfo */
1280
1281         if (!NT_STATUS_IS_OK(status)) {
1282                 /* Old file not found, so by definition new file is in fact newer */
1283                 DEBUG(10,("file_version_is_newer: Can't open old file [%s], "
1284                           "errno = %d\n", smb_fname_str_dbg(smb_fname),
1285                           errno));
1286                 ret = 1;
1287                 goto done;
1288
1289         } else {
1290                 ret = get_file_version(fsp, old_file, &old_major, &old_minor);
1291                 if (ret == -1) {
1292                         goto error_exit;
1293                 }
1294
1295                 if (!ret) {
1296                         DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
1297                                          old_file));
1298                         use_version = false;
1299                         if (SMB_VFS_FSTAT(fsp, &st) == -1) {
1300                                  goto error_exit;
1301                         }
1302                         old_create_time = convert_timespec_to_time_t(st.st_ex_mtime);
1303                         DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n",
1304                                 (long)old_create_time));
1305                 }
1306         }
1307         close_file(NULL, fsp, NORMAL_CLOSE);
1308         fsp = NULL;
1309
1310         /* Get file version info (if available) for new file */
1311         status = driver_unix_convert(conn, new_file, &smb_fname);
1312         if (!NT_STATUS_IS_OK(status)) {
1313                 goto error_exit;
1314         }
1315
1316         status = SMB_VFS_CREATE_FILE(
1317                 conn,                                   /* conn */
1318                 NULL,                                   /* req */
1319                 0,                                      /* root_dir_fid */
1320                 smb_fname,                              /* fname */
1321                 FILE_GENERIC_READ,                      /* access_mask */
1322                 FILE_SHARE_READ | FILE_SHARE_WRITE,     /* share_access */
1323                 FILE_OPEN,                              /* create_disposition*/
1324                 0,                                      /* create_options */
1325                 FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
1326                 INTERNAL_OPEN_ONLY,                     /* oplock_request */
1327                 0,                                      /* allocation_size */
1328                 0,                                      /* private_flags */
1329                 NULL,                                   /* sd */
1330                 NULL,                                   /* ea_list */
1331                 &fsp,                                   /* result */
1332                 NULL);                                  /* pinfo */
1333
1334         if (!NT_STATUS_IS_OK(status)) {
1335                 /* New file not found, this shouldn't occur if the caller did its job */
1336                 DEBUG(3,("file_version_is_newer: Can't open new file [%s], "
1337                          "errno = %d\n", smb_fname_str_dbg(smb_fname), errno));
1338                 goto error_exit;
1339
1340         } else {
1341                 ret = get_file_version(fsp, new_file, &new_major, &new_minor);
1342                 if (ret == -1) {
1343                         goto error_exit;
1344                 }
1345
1346                 if (!ret) {
1347                         DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
1348                                          new_file));
1349                         use_version = false;
1350                         if (SMB_VFS_FSTAT(fsp, &st) == -1) {
1351                                 goto error_exit;
1352                         }
1353                         new_create_time = convert_timespec_to_time_t(st.st_ex_mtime);
1354                         DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n",
1355                                 (long)new_create_time));
1356                 }
1357         }
1358         close_file(NULL, fsp, NORMAL_CLOSE);
1359         fsp = NULL;
1360
1361         if (use_version && (new_major != old_major || new_minor != old_minor)) {
1362                 /* Compare versions and choose the larger version number */
1363                 if (new_major > old_major ||
1364                         (new_major == old_major && new_minor > old_minor)) {
1365
1366                         DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
1367                         ret = 1;
1368                         goto done;
1369                 }
1370                 else {
1371                         DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
1372                         ret = 0;
1373                         goto done;
1374                 }
1375
1376         } else {
1377                 /* Compare modification time/dates and choose the newest time/date */
1378                 if (new_create_time > old_create_time) {
1379                         DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
1380                         ret = 1;
1381                         goto done;
1382                 }
1383                 else {
1384                         DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
1385                         ret = 0;
1386                         goto done;
1387                 }
1388         }
1389
1390  error_exit:
1391         if(fsp)
1392                 close_file(NULL, fsp, NORMAL_CLOSE);
1393         ret = -1;
1394  done:
1395         TALLOC_FREE(smb_fname);
1396         return ret;
1397 }
1398
1399 /****************************************************************************
1400 Determine the correct cVersion associated with an architecture and driver
1401 ****************************************************************************/
1402 static uint32 get_correct_cversion(struct pipes_struct *p,
1403                                    const char *architecture,
1404                                    const char *driverpath_in,
1405                                    WERROR *perr)
1406 {
1407         int               cversion;
1408         NTSTATUS          nt_status;
1409         struct smb_filename *smb_fname = NULL;
1410         char *driverpath = NULL;
1411         files_struct      *fsp = NULL;
1412         connection_struct *conn = NULL;
1413         NTSTATUS status;
1414         char *oldcwd;
1415         fstring printdollar;
1416         int printdollar_snum;
1417
1418         *perr = WERR_INVALID_PARAM;
1419
1420         /* If architecture is Windows 95/98/ME, the version is always 0. */
1421         if (strcmp(architecture, SPL_ARCH_WIN40) == 0) {
1422                 DEBUG(10,("get_correct_cversion: Driver is Win9x, cversion = 0\n"));
1423                 *perr = WERR_OK;
1424                 return 0;
1425         }
1426
1427         /* If architecture is Windows x64, the version is always 3. */
1428         if (strcmp(architecture, SPL_ARCH_X64) == 0) {
1429                 DEBUG(10,("get_correct_cversion: Driver is x64, cversion = 3\n"));
1430                 *perr = WERR_OK;
1431                 return 3;
1432         }
1433
1434         fstrcpy(printdollar, "print$");
1435
1436         printdollar_snum = find_service(printdollar);
1437         if (printdollar_snum == -1) {
1438                 *perr = WERR_NO_SUCH_SHARE;
1439                 return -1;
1440         }
1441
1442         nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum,
1443                                        lp_pathname(printdollar_snum),
1444                                        p->server_info, &oldcwd);
1445         if (!NT_STATUS_IS_OK(nt_status)) {
1446                 DEBUG(0,("get_correct_cversion: create_conn_struct "
1447                          "returned %s\n", nt_errstr(nt_status)));
1448                 *perr = ntstatus_to_werror(nt_status);
1449                 return -1;
1450         }
1451
1452         /* Open the driver file (Portable Executable format) and determine the
1453          * deriver the cversion. */
1454         driverpath = talloc_asprintf(talloc_tos(),
1455                                         "%s/%s",
1456                                         architecture,
1457                                         driverpath_in);
1458         if (!driverpath) {
1459                 *perr = WERR_NOMEM;
1460                 goto error_exit;
1461         }
1462
1463         nt_status = driver_unix_convert(conn, driverpath, &smb_fname);
1464         if (!NT_STATUS_IS_OK(nt_status)) {
1465                 *perr = ntstatus_to_werror(nt_status);
1466                 goto error_exit;
1467         }
1468
1469         nt_status = vfs_file_exist(conn, smb_fname);
1470         if (!NT_STATUS_IS_OK(nt_status)) {
1471                 *perr = WERR_BADFILE;
1472                 goto error_exit;
1473         }
1474
1475         status = SMB_VFS_CREATE_FILE(
1476                 conn,                                   /* conn */
1477                 NULL,                                   /* req */
1478                 0,                                      /* root_dir_fid */
1479                 smb_fname,                              /* fname */
1480                 FILE_GENERIC_READ,                      /* access_mask */
1481                 FILE_SHARE_READ | FILE_SHARE_WRITE,     /* share_access */
1482                 FILE_OPEN,                              /* create_disposition*/
1483                 0,                                      /* create_options */
1484                 FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
1485                 INTERNAL_OPEN_ONLY,                     /* oplock_request */
1486                 0,                                      /* private_flags */
1487                 0,                                      /* allocation_size */
1488                 NULL,                                   /* sd */
1489                 NULL,                                   /* ea_list */
1490                 &fsp,                                   /* result */
1491                 NULL);                                  /* pinfo */
1492
1493         if (!NT_STATUS_IS_OK(status)) {
1494                 DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = "
1495                          "%d\n", smb_fname_str_dbg(smb_fname), errno));
1496                 *perr = WERR_ACCESS_DENIED;
1497                 goto error_exit;
1498         } else {
1499                 uint32 major;
1500                 uint32 minor;
1501                 int    ret;
1502
1503                 ret = get_file_version(fsp, smb_fname->base_name, &major, &minor);
1504                 if (ret == -1) goto error_exit;
1505
1506                 if (!ret) {
1507                         DEBUG(6,("get_correct_cversion: Version info not "
1508                                  "found [%s]\n",
1509                                  smb_fname_str_dbg(smb_fname)));
1510                         goto error_exit;
1511                 }
1512
1513                 /*
1514                  * This is a Microsoft'ism. See references in MSDN to VER_FILEVERSION
1515                  * for more details. Version in this case is not just the version of the
1516                  * file, but the version in the sense of kernal mode (2) vs. user mode
1517                  * (3) drivers. Other bits of the version fields are the version info.
1518                  * JRR 010716
1519                 */
1520                 cversion = major & 0x0000ffff;
1521                 switch (cversion) {
1522                         case 2: /* WinNT drivers */
1523                         case 3: /* Win2K drivers */
1524                                 break;
1525
1526                         default:
1527                                 DEBUG(6,("get_correct_cversion: cversion "
1528                                          "invalid [%s]  cversion = %d\n",
1529                                          smb_fname_str_dbg(smb_fname),
1530                                          cversion));
1531                                 goto error_exit;
1532                 }
1533
1534                 DEBUG(10,("get_correct_cversion: Version info found [%s] major"
1535                           " = 0x%x  minor = 0x%x\n",
1536                           smb_fname_str_dbg(smb_fname), major, minor));
1537         }
1538
1539         DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
1540                   smb_fname_str_dbg(smb_fname), cversion));
1541
1542         goto done;
1543
1544  error_exit:
1545         cversion = -1;
1546  done:
1547         TALLOC_FREE(smb_fname);
1548         if (fsp != NULL) {
1549                 close_file(NULL, fsp, NORMAL_CLOSE);
1550         }
1551         if (conn != NULL) {
1552                 vfs_ChDir(conn, oldcwd);
1553                 conn_free(conn);
1554         }
1555         if (cversion != -1) {
1556                 *perr = WERR_OK;
1557         }
1558         return cversion;
1559 }
1560
1561 /****************************************************************************
1562 ****************************************************************************/
1563
1564 #define strip_driver_path(_mem_ctx, _element) do { \
1565         if (_element && ((_p = strrchr((_element), '\\')) != NULL)) { \
1566                 (_element) = talloc_asprintf((_mem_ctx), "%s", _p+1); \
1567                 W_ERROR_HAVE_NO_MEMORY((_element)); \
1568         } \
1569 } while (0);
1570
1571 static WERROR clean_up_driver_struct_level(TALLOC_CTX *mem_ctx,
1572                                            struct pipes_struct *rpc_pipe,
1573                                            const char *architecture,
1574                                            const char **driver_path,
1575                                            const char **data_file,
1576                                            const char **config_file,
1577                                            const char **help_file,
1578                                            struct spoolss_StringArray *dependent_files,
1579                                            uint32_t *version)
1580 {
1581         const char *short_architecture;
1582         int i;
1583         WERROR err;
1584         char *_p;
1585
1586         if (!*driver_path || !*data_file || !*config_file) {
1587                 return WERR_INVALID_PARAM;
1588         }
1589
1590         /* clean up the driver name.
1591          * we can get .\driver.dll
1592          * or worse c:\windows\system\driver.dll !
1593          */
1594         /* using an intermediate string to not have overlaping memcpy()'s */
1595
1596         strip_driver_path(mem_ctx, *driver_path);
1597         strip_driver_path(mem_ctx, *data_file);
1598         strip_driver_path(mem_ctx, *config_file);
1599         if (help_file) {
1600                 strip_driver_path(mem_ctx, *help_file);
1601         }
1602
1603         if (dependent_files && dependent_files->string) {
1604                 for (i=0; dependent_files->string[i]; i++) {
1605                         strip_driver_path(mem_ctx, dependent_files->string[i]);
1606                 }
1607         }
1608
1609         short_architecture = get_short_archi(architecture);
1610         if (!short_architecture) {
1611                 return WERR_UNKNOWN_PRINTER_DRIVER;
1612         }
1613
1614         /* jfm:7/16/2000 the client always sends the cversion=0.
1615          * The server should check which version the driver is by reading
1616          * the PE header of driver->driverpath.
1617          *
1618          * For Windows 95/98 the version is 0 (so the value sent is correct)
1619          * For Windows NT (the architecture doesn't matter)
1620          *      NT 3.1: cversion=0
1621          *      NT 3.5/3.51: cversion=1
1622          *      NT 4: cversion=2
1623          *      NT2K: cversion=3
1624          */
1625
1626         *version = get_correct_cversion(rpc_pipe, short_architecture,
1627                                         *driver_path, &err);
1628         if (*version == -1) {
1629                 return err;
1630         }
1631
1632         return WERR_OK;
1633 }
1634
1635 /****************************************************************************
1636 ****************************************************************************/
1637
1638 WERROR clean_up_driver_struct(TALLOC_CTX *mem_ctx,
1639                               struct pipes_struct *rpc_pipe,
1640                               struct spoolss_AddDriverInfoCtr *r)
1641 {
1642         switch (r->level) {
1643         case 3:
1644                 return clean_up_driver_struct_level(mem_ctx, rpc_pipe,
1645                                                     r->info.info3->architecture,
1646                                                     &r->info.info3->driver_path,
1647                                                     &r->info.info3->data_file,
1648                                                     &r->info.info3->config_file,
1649                                                     &r->info.info3->help_file,
1650                                                     r->info.info3->dependent_files,
1651                                                     &r->info.info3->version);
1652         case 6:
1653                 return clean_up_driver_struct_level(mem_ctx, rpc_pipe,
1654                                                     r->info.info6->architecture,
1655                                                     &r->info.info6->driver_path,
1656                                                     &r->info.info6->data_file,
1657                                                     &r->info.info6->config_file,
1658                                                     &r->info.info6->help_file,
1659                                                     r->info.info6->dependent_files,
1660                                                     &r->info.info6->version);
1661         default:
1662                 return WERR_NOT_SUPPORTED;
1663         }
1664 }
1665
1666 /****************************************************************************
1667  This function sucks and should be replaced. JRA.
1668 ****************************************************************************/
1669
1670 static void convert_level_6_to_level3(struct spoolss_AddDriverInfo3 *dst,
1671                                       const struct spoolss_AddDriverInfo6 *src)
1672 {
1673         dst->version            = src->version;
1674
1675         dst->driver_name        = src->driver_name;
1676         dst->architecture       = src->architecture;
1677         dst->driver_path        = src->driver_path;
1678         dst->data_file          = src->data_file;
1679         dst->config_file        = src->config_file;
1680         dst->help_file          = src->help_file;
1681         dst->monitor_name       = src->monitor_name;
1682         dst->default_datatype   = src->default_datatype;
1683         dst->_ndr_size_dependent_files = src->_ndr_size_dependent_files;
1684         dst->dependent_files    = src->dependent_files;
1685 }
1686
1687 /****************************************************************************
1688 ****************************************************************************/
1689
1690 static WERROR move_driver_file_to_download_area(TALLOC_CTX *mem_ctx,
1691                                                 connection_struct *conn,
1692                                                 const char *driver_file,
1693                                                 const char *short_architecture,
1694                                                 uint32_t driver_version,
1695                                                 uint32_t version)
1696 {
1697         struct smb_filename *smb_fname_old = NULL;
1698         struct smb_filename *smb_fname_new = NULL;
1699         char *old_name = NULL;
1700         char *new_name = NULL;
1701         NTSTATUS status;
1702         WERROR ret;
1703
1704         old_name = talloc_asprintf(mem_ctx, "%s/%s",
1705                                    short_architecture, driver_file);
1706         W_ERROR_HAVE_NO_MEMORY(old_name);
1707
1708         new_name = talloc_asprintf(mem_ctx, "%s/%d/%s",
1709                                    short_architecture, driver_version, driver_file);
1710         if (new_name == NULL) {
1711                 TALLOC_FREE(old_name);
1712                 return WERR_NOMEM;
1713         }
1714
1715         if (version != -1 && (version = file_version_is_newer(conn, old_name, new_name)) > 0) {
1716
1717                 status = driver_unix_convert(conn, old_name, &smb_fname_old);
1718                 if (!NT_STATUS_IS_OK(status)) {
1719                         ret = WERR_NOMEM;
1720                         goto out;
1721                 }
1722
1723                 /* Setup a synthetic smb_filename struct */
1724                 smb_fname_new = TALLOC_ZERO_P(mem_ctx, struct smb_filename);
1725                 if (!smb_fname_new) {
1726                         ret = WERR_NOMEM;
1727                         goto out;
1728                 }
1729
1730                 smb_fname_new->base_name = new_name;
1731
1732                 DEBUG(10,("move_driver_file_to_download_area: copying '%s' to "
1733                           "'%s'\n", smb_fname_old->base_name,
1734                           smb_fname_new->base_name));
1735
1736                 status = copy_file(mem_ctx, conn, smb_fname_old, smb_fname_new,
1737                                    OPENX_FILE_EXISTS_TRUNCATE |
1738                                    OPENX_FILE_CREATE_IF_NOT_EXIST,
1739                                    0, false);
1740
1741                 if (!NT_STATUS_IS_OK(status)) {
1742                         DEBUG(0,("move_driver_file_to_download_area: Unable "
1743                                  "to rename [%s] to [%s]: %s\n",
1744                                  smb_fname_old->base_name, new_name,
1745                                  nt_errstr(status)));
1746                         ret = WERR_ACCESS_DENIED;
1747                         goto out;
1748                 }
1749         }
1750
1751         ret = WERR_OK;
1752  out:
1753         TALLOC_FREE(smb_fname_old);
1754         TALLOC_FREE(smb_fname_new);
1755         return ret;
1756 }
1757
1758 WERROR move_driver_to_download_area(struct pipes_struct *p,
1759                                     struct spoolss_AddDriverInfoCtr *r,
1760                                     WERROR *perr)
1761 {
1762         struct spoolss_AddDriverInfo3 *driver;
1763         struct spoolss_AddDriverInfo3 converted_driver;
1764         const char *short_architecture;
1765         struct smb_filename *smb_dname = NULL;
1766         char *new_dir = NULL;
1767         connection_struct *conn = NULL;
1768         NTSTATUS nt_status;
1769         int i;
1770         TALLOC_CTX *ctx = talloc_tos();
1771         int ver = 0;
1772         char *oldcwd;
1773         fstring printdollar;
1774         int printdollar_snum;
1775
1776         *perr = WERR_OK;
1777
1778         switch (r->level) {
1779         case 3:
1780                 driver = r->info.info3;
1781                 break;
1782         case 6:
1783                 convert_level_6_to_level3(&converted_driver, r->info.info6);
1784                 driver = &converted_driver;
1785                 break;
1786         default:
1787                 DEBUG(0,("move_driver_to_download_area: Unknown info level (%u)\n", (unsigned int)r->level));
1788                 return WERR_UNKNOWN_LEVEL;
1789         }
1790
1791         short_architecture = get_short_archi(driver->architecture);
1792         if (!short_architecture) {
1793                 return WERR_UNKNOWN_PRINTER_DRIVER;
1794         }
1795
1796         fstrcpy(printdollar, "print$");
1797
1798         printdollar_snum = find_service(printdollar);
1799         if (printdollar_snum == -1) {
1800                 *perr = WERR_NO_SUCH_SHARE;
1801                 return WERR_NO_SUCH_SHARE;
1802         }
1803
1804         nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum,
1805                                        lp_pathname(printdollar_snum),
1806                                        p->server_info, &oldcwd);
1807         if (!NT_STATUS_IS_OK(nt_status)) {
1808                 DEBUG(0,("move_driver_to_download_area: create_conn_struct "
1809                          "returned %s\n", nt_errstr(nt_status)));
1810                 *perr = ntstatus_to_werror(nt_status);
1811                 return *perr;
1812         }
1813
1814         new_dir = talloc_asprintf(ctx,
1815                                 "%s/%d",
1816                                 short_architecture,
1817                                 driver->version);
1818         if (!new_dir) {
1819                 *perr = WERR_NOMEM;
1820                 goto err_exit;
1821         }
1822         nt_status = driver_unix_convert(conn, new_dir, &smb_dname);
1823         if (!NT_STATUS_IS_OK(nt_status)) {
1824                 *perr = WERR_NOMEM;
1825                 goto err_exit;
1826         }
1827
1828         DEBUG(5,("Creating first directory: %s\n", smb_dname->base_name));
1829
1830         create_directory(conn, NULL, smb_dname);
1831
1832         /* For each driver file, archi\filexxx.yyy, if there is a duplicate file
1833          * listed for this driver which has already been moved, skip it (note:
1834          * drivers may list the same file name several times. Then check if the
1835          * file already exists in archi\version\, if so, check that the version
1836          * info (or time stamps if version info is unavailable) is newer (or the
1837          * date is later). If it is, move it to archi\version\filexxx.yyy.
1838          * Otherwise, delete the file.
1839          *
1840          * If a file is not moved to archi\version\ because of an error, all the
1841          * rest of the 'unmoved' driver files are removed from archi\. If one or
1842          * more of the driver's files was already moved to archi\version\, it
1843          * potentially leaves the driver in a partially updated state. Version
1844          * trauma will most likely occur if an client attempts to use any printer
1845          * bound to the driver. Perhaps a rewrite to make sure the moves can be
1846          * done is appropriate... later JRR
1847          */
1848
1849         DEBUG(5,("Moving files now !\n"));
1850
1851         if (driver->driver_path && strlen(driver->driver_path)) {
1852
1853                 *perr = move_driver_file_to_download_area(ctx,
1854                                                           conn,
1855                                                           driver->driver_path,
1856                                                           short_architecture,
1857                                                           driver->version,
1858                                                           ver);
1859                 if (!W_ERROR_IS_OK(*perr)) {
1860                         if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
1861                                 ver = -1;
1862                         }
1863                         goto err_exit;
1864                 }
1865         }
1866
1867         if (driver->data_file && strlen(driver->data_file)) {
1868                 if (!strequal(driver->data_file, driver->driver_path)) {
1869
1870                         *perr = move_driver_file_to_download_area(ctx,
1871                                                                   conn,
1872                                                                   driver->data_file,
1873                                                                   short_architecture,
1874                                                                   driver->version,
1875                                                                   ver);
1876                         if (!W_ERROR_IS_OK(*perr)) {
1877                                 if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
1878                                         ver = -1;
1879                                 }
1880                                 goto err_exit;
1881                         }
1882                 }
1883         }
1884
1885         if (driver->config_file && strlen(driver->config_file)) {
1886                 if (!strequal(driver->config_file, driver->driver_path) &&
1887                     !strequal(driver->config_file, driver->data_file)) {
1888
1889                         *perr = move_driver_file_to_download_area(ctx,
1890                                                                   conn,
1891                                                                   driver->config_file,
1892                                                                   short_architecture,
1893                                                                   driver->version,
1894                                                                   ver);
1895                         if (!W_ERROR_IS_OK(*perr)) {
1896                                 if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
1897                                         ver = -1;
1898                                 }
1899                                 goto err_exit;
1900                         }
1901                 }
1902         }
1903
1904         if (driver->help_file && strlen(driver->help_file)) {
1905                 if (!strequal(driver->help_file, driver->driver_path) &&
1906                     !strequal(driver->help_file, driver->data_file) &&
1907                     !strequal(driver->help_file, driver->config_file)) {
1908
1909                         *perr = move_driver_file_to_download_area(ctx,
1910                                                                   conn,
1911                                                                   driver->help_file,
1912                                                                   short_architecture,
1913                                                                   driver->version,
1914                                                                   ver);
1915                         if (!W_ERROR_IS_OK(*perr)) {
1916                                 if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
1917                                         ver = -1;
1918                                 }
1919                                 goto err_exit;
1920                         }
1921                 }
1922         }
1923
1924         if (driver->dependent_files && driver->dependent_files->string) {
1925                 for (i=0; driver->dependent_files->string[i]; i++) {
1926                         if (!strequal(driver->dependent_files->string[i], driver->driver_path) &&
1927                             !strequal(driver->dependent_files->string[i], driver->data_file) &&
1928                             !strequal(driver->dependent_files->string[i], driver->config_file) &&
1929                             !strequal(driver->dependent_files->string[i], driver->help_file)) {
1930                                 int j;
1931                                 for (j=0; j < i; j++) {
1932                                         if (strequal(driver->dependent_files->string[i], driver->dependent_files->string[j])) {
1933                                                 goto NextDriver;
1934                                         }
1935                                 }
1936
1937                                 *perr = move_driver_file_to_download_area(ctx,
1938                                                                           conn,
1939                                                                           driver->dependent_files->string[i],
1940                                                                           short_architecture,
1941                                                                           driver->version,
1942                                                                           ver);
1943                                 if (!W_ERROR_IS_OK(*perr)) {
1944                                         if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
1945                                                 ver = -1;
1946                                         }
1947                                         goto err_exit;
1948                                 }
1949                         }
1950                 NextDriver: ;
1951                 }
1952         }
1953
1954   err_exit:
1955         TALLOC_FREE(smb_dname);
1956
1957         if (conn != NULL) {
1958                 vfs_ChDir(conn, oldcwd);
1959                 conn_free(conn);
1960         }
1961
1962         if (W_ERROR_EQUAL(*perr, WERR_OK)) {
1963                 return WERR_OK;
1964         }
1965         if (ver == -1) {
1966                 return WERR_UNKNOWN_PRINTER_DRIVER;
1967         }
1968         return (*perr);
1969 }
1970
1971 /****************************************************************************
1972 ****************************************************************************/
1973 int pack_devicemode(struct spoolss_DeviceMode *devmode, uint8 *buf, int buflen)
1974 {
1975         enum ndr_err_code ndr_err;
1976         DATA_BLOB blob;
1977         int len = 0;
1978
1979         if (devmode) {
1980                 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(),
1981                                                devmode,
1982                                                (ndr_push_flags_fn_t)
1983                                                ndr_push_spoolss_DeviceMode);
1984                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1985                         DEBUG(10, ("pack_devicemode: "
1986                                    "error encoding spoolss_DeviceMode\n"));
1987                         goto done;
1988                 }
1989         } else {
1990                 ZERO_STRUCT(blob);
1991         }
1992
1993         len = tdb_pack(buf, buflen, "B", blob.length, blob.data);
1994
1995         if (devmode) {
1996                 DEBUG(8, ("Packed devicemode [%s]\n", devmode->formname));
1997         }
1998
1999 done:
2000         return len;
2001 }
2002
2003 /****************************************************************************
2004 ****************************************************************************/
2005 int unpack_devicemode(TALLOC_CTX *mem_ctx,
2006                       const uint8 *buf, int buflen,
2007                       struct spoolss_DeviceMode **devmode)
2008 {
2009         struct spoolss_DeviceMode *dm;
2010         enum ndr_err_code ndr_err;
2011         char *data = NULL;
2012         int data_len = 0;
2013         DATA_BLOB blob;
2014         int len = 0;
2015
2016         *devmode = NULL;
2017
2018         len = tdb_unpack(buf, buflen, "B", &data_len, &data);
2019         if (!data) {
2020                 return len;
2021         }
2022
2023         dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
2024         if (!dm) {
2025                 goto done;
2026         }
2027
2028         blob = data_blob_const(data, data_len);
2029
2030         ndr_err = ndr_pull_struct_blob(&blob, dm, dm,
2031                         (ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode);
2032         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2033                 DEBUG(10, ("unpack_devicemode: "
2034                            "error parsing spoolss_DeviceMode\n"));
2035                 goto done;
2036         }
2037
2038         DEBUG(8, ("Unpacked devicemode [%s](%s)\n",
2039                   dm->devicename, dm->formname));
2040         if (dm->driverextra_data.data) {
2041                 DEBUG(8, ("with a private section of %d bytes\n",
2042                           dm->__driverextra_length));
2043         }
2044
2045         *devmode = dm;
2046
2047 done:
2048         SAFE_FREE(data);
2049         return len;
2050 }
2051
2052 /****************************************************************************
2053  Pack all values in all printer keys
2054  ***************************************************************************/
2055
2056 static int pack_values(NT_PRINTER_DATA *data, uint8 *buf, int buflen)
2057 {
2058         int             len = 0;
2059         int             i, j;
2060         struct regval_blob      *val;
2061         struct regval_ctr       *val_ctr;
2062         char *path = NULL;
2063         int             num_values;
2064
2065         if ( !data )
2066                 return 0;
2067
2068         /* loop over all keys */
2069
2070         for ( i=0; i<data->num_keys; i++ ) {
2071                 val_ctr = data->keys[i].values;
2072                 num_values = regval_ctr_numvals( val_ctr );
2073
2074                 /* pack the keyname followed by a empty value */
2075
2076                 len += tdb_pack(buf+len, buflen-len, "pPdB",
2077                                 &data->keys[i].name,
2078                                 data->keys[i].name,
2079                                 REG_NONE,
2080                                 0,
2081                                 NULL);
2082
2083                 /* now loop over all values */
2084
2085                 for ( j=0; j<num_values; j++ ) {
2086                         /* pathname should be stored as <key>\<value> */
2087
2088                         val = regval_ctr_specific_value( val_ctr, j );
2089                         if (asprintf(&path, "%s\\%s",
2090                                         data->keys[i].name,
2091                                         regval_name(val)) < 0) {
2092                                 return -1;
2093                         }
2094
2095                         len += tdb_pack(buf+len, buflen-len, "pPdB",
2096                                         val,
2097                                         path,
2098                                         regval_type(val),
2099                                         regval_size(val),
2100                                         regval_data_p(val) );
2101
2102                         DEBUG(8,("specific: [%s], len: %d\n", regval_name(val), regval_size(val)));
2103                         SAFE_FREE(path);
2104                 }
2105
2106         }
2107
2108         /* terminator */
2109
2110         len += tdb_pack(buf+len, buflen-len, "p", NULL);
2111
2112         return len;
2113 }
2114
2115
2116 /****************************************************************************
2117  Delete a printer - this just deletes the printer info file, any open
2118  handles are not affected.
2119 ****************************************************************************/
2120
2121 uint32 del_a_printer(const char *sharename)
2122 {
2123         TDB_DATA kbuf;
2124         char *printdb_path = NULL;
2125         TALLOC_CTX *ctx = talloc_tos();
2126
2127         kbuf = make_printer_tdbkey(ctx, sharename);
2128         tdb_delete(tdb_printers, kbuf);
2129
2130         kbuf= make_printers_secdesc_tdbkey(ctx, sharename);
2131         tdb_delete(tdb_printers, kbuf);
2132
2133         close_all_print_db();
2134
2135         if (geteuid() == sec_initial_uid()) {
2136                 if (asprintf(&printdb_path, "%s%s.tdb",
2137                                 cache_path("printing/"),
2138                                 sharename) < 0) {
2139                         return (uint32)-1;
2140                 }
2141                 unlink(printdb_path);
2142                 SAFE_FREE(printdb_path);
2143         }
2144
2145         return 0;
2146 }
2147
2148 /****************************************************************************
2149 ****************************************************************************/
2150 static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
2151 {
2152         uint8 *buf;
2153         int buflen, len;
2154         int retlen;
2155         WERROR ret;
2156         TDB_DATA kbuf, dbuf;
2157
2158         /*
2159          * in addprinter: no servername and the printer is the name
2160          * in setprinter: servername is \\server
2161          *                and printer is \\server\\printer
2162          *
2163          * Samba manages only local printers.
2164          * we currently don't support things like i
2165          * path=\\other_server\printer
2166          *
2167          * We only store the printername, not \\server\printername
2168          */
2169
2170         if ( info->servername[0] != '\0' ) {
2171                 trim_string(info->printername, info->servername, NULL);
2172                 trim_char(info->printername, '\\', '\0');
2173                 info->servername[0]='\0';
2174         }
2175
2176         /*
2177          * JFM: one day I'll forget.
2178          * below that's info->portname because that's the SAMBA sharename
2179          * and I made NT 'thinks' it's the portname
2180          * the info->sharename is the thing you can name when you add a printer
2181          * that's the short-name when you create shared printer for 95/98
2182          * So I've made a limitation in SAMBA: you can only have 1 printer model
2183          * behind a SAMBA share.
2184          */
2185
2186         buf = NULL;
2187         buflen = 0;
2188
2189  again:
2190         len = 0;
2191         len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffPfffff",
2192                         info->attributes,
2193                         info->priority,
2194                         info->default_priority,
2195                         info->starttime,
2196                         info->untiltime,
2197                         info->status,
2198                         info->cjobs,
2199                         info->averageppm,
2200                         info->changeid,
2201                         info->c_setprinter,
2202                         info->setuptime,
2203                         info->servername,
2204                         info->printername,
2205                         info->sharename,
2206                         info->portname,
2207                         info->drivername,
2208                         info->comment,
2209                         info->location,
2210                         info->sepfile,
2211                         info->printprocessor,
2212                         info->datatype,
2213                         info->parameters);
2214
2215         len += pack_devicemode(info->devmode, buf+len, buflen-len);
2216         retlen = pack_values( info->data, buf+len, buflen-len );
2217         if (retlen == -1) {
2218                 ret = WERR_NOMEM;
2219                 goto done;
2220         }
2221         len += retlen;
2222
2223         if (buflen != len) {
2224                 buf = (uint8 *)SMB_REALLOC(buf, len);
2225                 if (!buf) {
2226                         DEBUG(0,("update_a_printer_2: failed to enlarge buffer!\n"));
2227                         ret = WERR_NOMEM;
2228                         goto done;
2229                 }
2230                 buflen = len;
2231                 goto again;
2232         }
2233
2234         kbuf = make_printer_tdbkey(talloc_tos(), info->sharename );
2235
2236         dbuf.dptr = buf;
2237         dbuf.dsize = len;
2238
2239         ret = (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) == 0? WERR_OK : WERR_NOMEM);
2240
2241 done:
2242         if (!W_ERROR_IS_OK(ret))
2243                 DEBUG(8, ("error updating printer to tdb on disk\n"));
2244
2245         SAFE_FREE(buf);
2246
2247         DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n",
2248                  info->sharename, info->drivername, info->portname, len));
2249
2250         return ret;
2251 }
2252
2253 /****************************************************************************
2254  Create and allocate a default devicemode.
2255 ****************************************************************************/
2256
2257 WERROR spoolss_create_default_devmode(TALLOC_CTX *mem_ctx,
2258                                       const char *devicename,
2259                                       struct spoolss_DeviceMode **devmode)
2260 {
2261         struct spoolss_DeviceMode *dm;
2262         char *dname;
2263
2264         dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
2265         if (dm == NULL) {
2266                 return WERR_NOMEM;
2267         }
2268
2269         dname = talloc_asprintf(dm, "%s", devicename);
2270         if (dname == NULL) {
2271                 return WERR_NOMEM;
2272         }
2273         if (strlen(dname) > MAXDEVICENAME) {
2274                 dname[MAXDEVICENAME] = '\0';
2275         }
2276         dm->devicename = dname;
2277
2278         dm->formname = talloc_strdup(dm, "Letter");
2279         if (dm->formname == NULL) {
2280                 return WERR_NOMEM;
2281         }
2282
2283         dm->specversion          = DMSPEC_NT4_AND_ABOVE;
2284         dm->driverversion        = 0x0400;
2285         dm->size                 = 0x00DC;
2286         dm->__driverextra_length = 0;
2287         dm->fields               = DEVMODE_FORMNAME |
2288                                    DEVMODE_TTOPTION |
2289                                    DEVMODE_PRINTQUALITY |
2290                                    DEVMODE_DEFAULTSOURCE |
2291                                    DEVMODE_COPIES |
2292                                    DEVMODE_SCALE |
2293                                    DEVMODE_PAPERSIZE |
2294                                    DEVMODE_ORIENTATION;
2295         dm->orientation          = DMORIENT_PORTRAIT;
2296         dm->papersize            = DMPAPER_LETTER;
2297         dm->paperlength          = 0;
2298         dm->paperwidth           = 0;
2299         dm->scale                = 0x64;
2300         dm->copies               = 1;
2301         dm->defaultsource        = DMBIN_FORMSOURCE;
2302         dm->printquality         = DMRES_HIGH;           /* 0x0258 */
2303         dm->color                = DMRES_MONOCHROME;
2304         dm->duplex               = DMDUP_SIMPLEX;
2305         dm->yresolution          = 0;
2306         dm->ttoption             = DMTT_SUBDEV;
2307         dm->collate              = DMCOLLATE_FALSE;
2308         dm->icmmethod            = 0;
2309         dm->icmintent            = 0;
2310         dm->mediatype            = 0;
2311         dm->dithertype           = 0;
2312
2313         dm->logpixels            = 0;
2314         dm->bitsperpel           = 0;
2315         dm->pelswidth            = 0;
2316         dm->pelsheight           = 0;
2317         dm->displayflags         = 0;
2318         dm->displayfrequency     = 0;
2319         dm->reserved1            = 0;
2320         dm->reserved2            = 0;
2321         dm->panningwidth         = 0;
2322         dm->panningheight        = 0;
2323
2324         dm->driverextra_data.data = NULL;
2325         dm->driverextra_data.length = 0;
2326
2327         *devmode = dm;
2328         return WERR_OK;
2329 }
2330
2331 WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx,
2332                                       struct spoolss_security_descriptor **secdesc)
2333 {
2334         struct security_ace ace[7];     /* max number of ace entries */
2335         int i = 0;
2336         uint32_t sa;
2337         struct security_acl *psa = NULL;
2338         struct security_descriptor *psd = NULL;
2339         struct dom_sid adm_sid;
2340         size_t sd_size;
2341
2342         /* Create an ACE where Everyone is allowed to print */
2343
2344         sa = PRINTER_ACE_PRINT;
2345         init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
2346                      sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
2347
2348         /* Add the domain admins group if we are a DC */
2349
2350         if ( IS_DC ) {
2351                 struct dom_sid domadmins_sid;
2352
2353                 sid_compose(&domadmins_sid, get_global_sam_sid(),
2354                             DOMAIN_RID_ADMINS);
2355
2356                 sa = PRINTER_ACE_FULL_CONTROL;
2357                 init_sec_ace(&ace[i++], &domadmins_sid,
2358                         SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
2359                         SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
2360                 init_sec_ace(&ace[i++], &domadmins_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
2361                         sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
2362         }
2363         else if (secrets_fetch_domain_sid(lp_workgroup(), &adm_sid)) {
2364                 sid_append_rid(&adm_sid, DOMAIN_RID_ADMINISTRATOR);
2365
2366                 sa = PRINTER_ACE_FULL_CONTROL;
2367                 init_sec_ace(&ace[i++], &adm_sid,
2368                         SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
2369                         SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
2370                 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
2371                         sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
2372         }
2373
2374         /* add BUILTIN\Administrators as FULL CONTROL */
2375
2376         sa = PRINTER_ACE_FULL_CONTROL;
2377         init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
2378                 SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
2379                 SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
2380         init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
2381                 SEC_ACE_TYPE_ACCESS_ALLOWED,
2382                 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
2383
2384         /* add BUILTIN\Print Operators as FULL CONTROL */
2385
2386         sa = PRINTER_ACE_FULL_CONTROL;
2387         init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
2388                 SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
2389                 SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
2390         init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
2391                 SEC_ACE_TYPE_ACCESS_ALLOWED,
2392                 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
2393
2394         /* Make the security descriptor owned by the BUILTIN\Administrators */
2395
2396         /* The ACL revision number in rpc_secdesc.h differs from the one
2397            created by NT when setting ACE entries in printer
2398            descriptors.  NT4 complains about the property being edited by a
2399            NT5 machine. */
2400
2401         if ((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) != NULL) {
2402                 psd = make_sec_desc(mem_ctx,
2403                                     SD_REVISION,
2404                                     SEC_DESC_SELF_RELATIVE,
2405                                     &global_sid_Builtin_Administrators,
2406                                     &global_sid_Builtin_Administrators,
2407                                     NULL,
2408                                     psa,
2409                                     &sd_size);
2410         }
2411
2412         if (psd == NULL) {
2413                 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
2414                 return WERR_NOMEM;
2415         }
2416
2417         DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
2418                  (unsigned int)sd_size));
2419
2420         *secdesc = psd;
2421
2422         return WERR_OK;
2423 }
2424
2425 /****************************************************************************
2426  Allocate and initialize a new slot.
2427 ***************************************************************************/
2428
2429 int add_new_printer_key( NT_PRINTER_DATA *data, const char *name )
2430 {
2431         NT_PRINTER_KEY  *d;
2432         int             key_index;
2433         WERROR werr;
2434
2435         if ( !name || !data )
2436                 return -1;
2437
2438         /* allocate another slot in the NT_PRINTER_KEY array */
2439
2440         if ( !(d = TALLOC_REALLOC_ARRAY( data, data->keys, NT_PRINTER_KEY, data->num_keys+1)) ) {
2441                 DEBUG(0,("add_new_printer_key: Realloc() failed!\n"));
2442                 return -1;
2443         }
2444
2445         data->keys = d;
2446
2447         key_index = data->num_keys;
2448
2449         /* initialze new key */
2450
2451         data->keys[key_index].name = talloc_strdup( data, name );
2452
2453         werr = regval_ctr_init(data, &(data->keys[key_index].values));
2454         if (!W_ERROR_IS_OK(werr)) {
2455                 return -1;
2456         }
2457
2458         data->num_keys++;
2459
2460         DEBUG(10,("add_new_printer_key: Inserted new data key [%s]\n", name ));
2461
2462         return key_index;
2463 }
2464
2465 /****************************************************************************
2466  search for a registry key name in the existing printer data
2467  ***************************************************************************/
2468
2469 int delete_printer_key( NT_PRINTER_DATA *data, const char *name )
2470 {
2471         int i;
2472
2473         for ( i=0; i<data->num_keys; i++ ) {
2474                 if ( strequal( data->keys[i].name, name ) ) {
2475
2476                         /* cleanup memory */
2477
2478                         TALLOC_FREE( data->keys[i].name );
2479                         TALLOC_FREE( data->keys[i].values );
2480
2481                         /* if not the end of the array, move remaining elements down one slot */
2482
2483                         data->num_keys--;
2484                         if ( data->num_keys && (i < data->num_keys) )
2485                                 memmove( &data->keys[i], &data->keys[i+1], sizeof(NT_PRINTER_KEY)*(data->num_keys-i) );
2486
2487                         break;
2488                 }
2489         }
2490
2491
2492         return data->num_keys;
2493 }
2494
2495 /****************************************************************************
2496  search for a registry key name in the existing printer data
2497  ***************************************************************************/
2498
2499 int lookup_printerkey( NT_PRINTER_DATA *data, const char *name )
2500 {
2501         int             key_index = -1;
2502         int             i;
2503
2504         if ( !data || !name )
2505                 return -1;
2506
2507         DEBUG(12,("lookup_printerkey: Looking for [%s]\n", name));
2508
2509         /* loop over all existing keys */
2510
2511         for ( i=0; i<data->num_keys; i++ ) {
2512                 if ( strequal(data->keys[i].name, name) ) {
2513                         DEBUG(12,("lookup_printerkey: Found [%s]!\n", name));
2514                         key_index = i;
2515                         break;
2516
2517                 }
2518         }
2519
2520         return key_index;
2521 }
2522
2523 /****************************************************************************
2524  ***************************************************************************/
2525
2526 int get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **subkeys )
2527 {
2528         int     i, j;
2529         int     key_len;
2530         int     num_subkeys = 0;
2531         char    *p;
2532         fstring *subkeys_ptr = NULL;
2533         fstring subkeyname;
2534
2535         *subkeys = NULL;
2536
2537         if ( !data )
2538                 return 0;
2539
2540         if ( !key )
2541                 return -1;
2542
2543         /* special case of asking for the top level printer data registry key names */
2544
2545         if ( strlen(key) == 0 ) {
2546                 for ( i=0; i<data->num_keys; i++ ) {
2547
2548                         /* found a match, so allocate space and copy the name */
2549
2550                         if ( !(subkeys_ptr = SMB_REALLOC_ARRAY( subkeys_ptr, fstring, num_subkeys+2)) ) {
2551                                 DEBUG(0,("get_printer_subkeys: Realloc failed for [%d] entries!\n",
2552                                         num_subkeys+1));
2553                                 return -1;
2554                         }
2555
2556                         fstrcpy( subkeys_ptr[num_subkeys], data->keys[i].name );
2557                         num_subkeys++;
2558                 }
2559
2560                 goto done;
2561         }
2562
2563         /* asking for the subkeys of some key */
2564         /* subkey paths are stored in the key name using '\' as the delimiter */
2565
2566         for ( i=0; i<data->num_keys; i++ ) {
2567                 if ( StrnCaseCmp(data->keys[i].name, key, strlen(key)) == 0 ) {
2568
2569                         /* if we found the exact key, then break */
2570                         key_len = strlen( key );
2571                         if ( strlen(data->keys[i].name) == key_len )
2572                                 break;
2573
2574                         /* get subkey path */
2575
2576                         p = data->keys[i].name + key_len;
2577                         if ( *p == '\\' )
2578                                 p++;
2579                         fstrcpy( subkeyname, p );
2580                         if ( (p = strchr( subkeyname, '\\' )) )
2581                                 *p = '\0';
2582
2583                         /* don't add a key more than once */
2584
2585                         for ( j=0; j<num_subkeys; j++ ) {
2586                                 if ( strequal( subkeys_ptr[j], subkeyname ) )
2587                                         break;
2588                         }
2589
2590                         if ( j != num_subkeys )
2591                                 continue;
2592
2593                         /* found a match, so allocate space and copy the name */
2594
2595                         if ( !(subkeys_ptr = SMB_REALLOC_ARRAY( subkeys_ptr, fstring, num_subkeys+2)) ) {
2596                                 DEBUG(0,("get_printer_subkeys: Realloc failed for [%d] entries!\n",
2597                                         num_subkeys+1));
2598                                 return 0;
2599                         }
2600
2601                         fstrcpy( subkeys_ptr[num_subkeys], subkeyname );
2602                         num_subkeys++;
2603                 }
2604
2605         }
2606
2607         /* return error if the key was not found */
2608
2609         if ( i == data->num_keys ) {
2610                 SAFE_FREE(subkeys_ptr);
2611                 return -1;
2612         }
2613
2614 done:
2615         /* tag off the end */
2616
2617         if (num_subkeys)
2618                 fstrcpy(subkeys_ptr[num_subkeys], "" );
2619
2620         *subkeys = subkeys_ptr;
2621
2622         return num_subkeys;
2623 }
2624
2625 #ifdef HAVE_ADS
2626 static void map_sz_into_ctr(struct regval_ctr *ctr, const char *val_name,
2627                             const char *sz)
2628 {
2629         regval_ctr_delvalue(ctr, val_name);
2630         regval_ctr_addvalue_sz(ctr, val_name, sz);
2631 }
2632
2633 static void map_dword_into_ctr(struct regval_ctr *ctr, const char *val_name,
2634                                uint32 dword)
2635 {
2636         regval_ctr_delvalue(ctr, val_name);
2637         regval_ctr_addvalue(ctr, val_name, REG_DWORD,
2638                             (uint8 *) &dword, sizeof(dword));
2639 }
2640
2641 static void map_bool_into_ctr(struct regval_ctr *ctr, const char *val_name,
2642                               bool b)
2643 {
2644         uint8 bin_bool = (b ? 1 : 0);
2645         regval_ctr_delvalue(ctr, val_name);
2646         regval_ctr_addvalue(ctr, val_name, REG_BINARY,
2647                             (uint8 *) &bin_bool, sizeof(bin_bool));
2648 }
2649
2650 static void map_single_multi_sz_into_ctr(struct regval_ctr *ctr, const char *val_name,
2651                                          const char *multi_sz)
2652 {
2653         const char *a[2];
2654
2655         a[0] = multi_sz;
2656         a[1] = NULL;
2657
2658         regval_ctr_delvalue(ctr, val_name);
2659         regval_ctr_addvalue_multi_sz(ctr, val_name, a);
2660 }
2661
2662 /****************************************************************************
2663  * Map spoolss_PrinterInfo2 data into DsSpooler keys for publishing.
2664  *
2665  * @param mem_ctx  allocation context
2666  * @param info2    spoolss_PrinterInfo2 describing printer
2667  * @param pdata    the talloced printer data
2668  * @return bool    indicating success or failure
2669  ***************************************************************************/
2670
2671 static bool map_nt_printer_info2_to_dsspooler(TALLOC_CTX *mem_ctx,
2672                                               struct spoolss_PrinterInfo2 *info2,
2673                                               NT_PRINTER_DATA **pdata)
2674 {
2675         NT_PRINTER_DATA *data;
2676         struct regval_ctr *ctr = NULL;
2677         fstring longname;
2678         const char *dnssuffix;
2679         char *allocated_string = NULL;
2680         const char *ascii_str;
2681         int i;
2682
2683         data = talloc_zero(mem_ctx, NT_PRINTER_DATA);
2684         if (!data) return false;
2685
2686         /* init data */
2687         i = add_new_printer_key(data, SPOOL_DSSPOOLER_KEY);
2688         ctr = data->keys[i].values;
2689
2690         map_sz_into_ctr(ctr, SPOOL_REG_PRINTERNAME, info2->sharename);
2691         map_sz_into_ctr(ctr, SPOOL_REG_SHORTSERVERNAME, global_myname());
2692
2693         /* we make the assumption that the netbios name is the same
2694            as the DNS name sinc ethe former will be what we used to
2695            join the domain */
2696
2697         dnssuffix = get_mydnsdomname(talloc_tos());
2698         if (dnssuffix && *dnssuffix) {
2699                 fstr_sprintf( longname, "%s.%s", global_myname(), dnssuffix );
2700         } else {
2701                 fstrcpy( longname, global_myname() );
2702         }
2703
2704         map_sz_into_ctr(ctr, SPOOL_REG_SERVERNAME, longname);
2705
2706         if (asprintf(&allocated_string, "\\\\%s\\%s", longname, info2->sharename) == -1) {
2707                 talloc_free(data);
2708                 return false;
2709         }
2710         map_sz_into_ctr(ctr, SPOOL_REG_UNCNAME, allocated_string);
2711         SAFE_FREE(allocated_string);
2712
2713         map_dword_into_ctr(ctr, SPOOL_REG_VERSIONNUMBER, 4);
2714         map_sz_into_ctr(ctr, SPOOL_REG_DRIVERNAME, info2->drivername);
2715         map_sz_into_ctr(ctr, SPOOL_REG_LOCATION, info2->location);
2716         map_sz_into_ctr(ctr, SPOOL_REG_DESCRIPTION, info2->comment);
2717         map_single_multi_sz_into_ctr(ctr, SPOOL_REG_PORTNAME, info2->portname);
2718         map_sz_into_ctr(ctr, SPOOL_REG_PRINTSEPARATORFILE, info2->sepfile);
2719         map_dword_into_ctr(ctr, SPOOL_REG_PRINTSTARTTIME, info2->starttime);
2720         map_dword_into_ctr(ctr, SPOOL_REG_PRINTENDTIME, info2->untiltime);
2721         map_dword_into_ctr(ctr, SPOOL_REG_PRIORITY, info2->priority);
2722
2723         map_bool_into_ctr(ctr, SPOOL_REG_PRINTKEEPPRINTEDJOBS,
2724                           (info2->attributes &
2725                            PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS));
2726
2727         switch (info2->attributes & 0x3) {
2728         case 0:
2729                 ascii_str = SPOOL_REGVAL_PRINTWHILESPOOLING;
2730                 break;
2731         case 1:
2732                 ascii_str = SPOOL_REGVAL_PRINTAFTERSPOOLED;
2733                 break;
2734         case 2:
2735                 ascii_str = SPOOL_REGVAL_PRINTDIRECT;
2736                 break;
2737         default:
2738                 ascii_str = "unknown";
2739         }
2740         map_sz_into_ctr(ctr, SPOOL_REG_PRINTSPOOLING, ascii_str);
2741
2742         *pdata = data;
2743         return true;
2744 }
2745
2746 /*****************************************************************
2747  ****************************************************************/
2748
2749 static void store_printer_guid(const char *printer, struct GUID guid)
2750 {
2751         TALLOC_CTX *tmp_ctx;
2752         struct auth_serversupplied_info *server_info = NULL;
2753         const char *guid_str;
2754         DATA_BLOB blob;
2755         NTSTATUS status;
2756         WERROR result;
2757
2758         tmp_ctx = talloc_new(NULL);
2759         if (!tmp_ctx) {
2760                 DEBUG(0, ("store_printer_guid: Out of memory?!\n"));
2761                 return;
2762         }
2763
2764         status = make_server_info_system(tmp_ctx, &server_info);
2765         if (!NT_STATUS_IS_OK(status)) {
2766                 DEBUG(0, ("store_printer_guid: "
2767                           "Could not create system server_info\n"));
2768                 goto done;
2769         }
2770
2771         guid_str = GUID_string(tmp_ctx, &guid);
2772         if (!guid_str) {
2773                 DEBUG(0, ("store_printer_guid: Out of memory?!\n"));
2774                 goto done;
2775         }
2776
2777         /* We used to store this as a REG_BINARY but that causes
2778            Vista to whine */
2779
2780         if (!push_reg_sz(tmp_ctx, &blob, guid_str)) {
2781                 DEBUG(0, ("store_printer_guid: "
2782                           "Could not marshall string %s for objectGUID\n",
2783                           guid_str));
2784                 goto done;
2785         }
2786
2787         result = winreg_set_printer_dataex(tmp_ctx, server_info, printer,
2788                                            SPOOL_DSSPOOLER_KEY, "objectGUID",
2789                                            REG_SZ, blob.data, blob.length);
2790         if (!W_ERROR_IS_OK(result)) {
2791                 DEBUG(0, ("store_printer_guid: "
2792                           "Failed to store GUID for printer %s\n", printer));
2793         }
2794
2795 done:
2796         talloc_free(tmp_ctx);
2797 }
2798
2799 static WERROR nt_printer_publish_ads(ADS_STRUCT *ads,
2800                                      struct spoolss_PrinterInfo2 *pinfo2)
2801 {
2802         ADS_STATUS ads_rc;
2803         LDAPMessage *res;
2804         char *prt_dn = NULL, *srv_dn, *srv_cn_0, *srv_cn_escaped, *sharename_escaped;
2805         char *srv_dn_utf8, **srv_cn_utf8;
2806         TALLOC_CTX *ctx;
2807         ADS_MODLIST mods;
2808         const char *attrs[] = {"objectGUID", NULL};
2809         struct GUID guid;
2810         WERROR win_rc = WERR_OK;
2811         size_t converted_size;
2812         NT_PRINTER_DATA *pdata;
2813         const char *printer = pinfo2->sharename;
2814
2815         /* build the ads mods */
2816         ctx = talloc_init("nt_printer_publish_ads");
2817         if (ctx == NULL) {
2818                 return WERR_NOMEM;
2819         }
2820
2821         DEBUG(5, ("publishing printer %s\n", printer));
2822
2823         if (!map_nt_printer_info2_to_dsspooler(ctx, pinfo2, &pdata)) {
2824                 TALLOC_FREE(ctx);
2825                 return WERR_SERVER_UNAVAILABLE;
2826         }
2827
2828         /* figure out where to publish */
2829         ads_find_machine_acct(ads, &res, global_myname());
2830
2831         /* We use ldap_get_dn here as we need the answer
2832          * in utf8 to call ldap_explode_dn(). JRA. */
2833
2834         srv_dn_utf8 = ldap_get_dn((LDAP *)ads->ldap.ld, (LDAPMessage *)res);
2835         if (!srv_dn_utf8) {
2836                 TALLOC_FREE(ctx);
2837                 return WERR_SERVER_UNAVAILABLE;
2838         }
2839         ads_msgfree(ads, res);
2840         srv_cn_utf8 = ldap_explode_dn(srv_dn_utf8, 1);
2841         if (!srv_cn_utf8) {
2842                 TALLOC_FREE(ctx);
2843                 ldap_memfree(srv_dn_utf8);
2844                 return WERR_SERVER_UNAVAILABLE;
2845         }
2846         /* Now convert to CH_UNIX. */
2847         if (!pull_utf8_talloc(ctx, &srv_dn, srv_dn_utf8, &converted_size)) {
2848                 TALLOC_FREE(ctx);
2849                 ldap_memfree(srv_dn_utf8);
2850                 ldap_memfree(srv_cn_utf8);
2851                 return WERR_SERVER_UNAVAILABLE;
2852         }
2853         if (!pull_utf8_talloc(ctx, &srv_cn_0, srv_cn_utf8[0], &converted_size)) {
2854                 TALLOC_FREE(ctx);
2855                 ldap_memfree(srv_dn_utf8);
2856                 ldap_memfree(srv_cn_utf8);
2857                 TALLOC_FREE(srv_dn);
2858                 return WERR_SERVER_UNAVAILABLE;
2859         }
2860
2861         ldap_memfree(srv_dn_utf8);
2862         ldap_memfree(srv_cn_utf8);
2863
2864         srv_cn_escaped = escape_rdn_val_string_alloc(srv_cn_0);
2865         if (!srv_cn_escaped) {
2866                 TALLOC_FREE(ctx);
2867                 return WERR_SERVER_UNAVAILABLE;
2868         }
2869         sharename_escaped = escape_rdn_val_string_alloc(printer);
2870         if (!sharename_escaped) {
2871                 SAFE_FREE(srv_cn_escaped);
2872                 TALLOC_FREE(ctx);
2873                 return WERR_SERVER_UNAVAILABLE;
2874         }
2875
2876         prt_dn = talloc_asprintf(ctx, "cn=%s-%s,%s", srv_cn_escaped, sharename_escaped, srv_dn);
2877
2878         SAFE_FREE(srv_cn_escaped);
2879         SAFE_FREE(sharename_escaped);
2880
2881         mods = ads_init_mods(ctx);
2882
2883         if (mods == NULL) {
2884                 SAFE_FREE(prt_dn);
2885                 TALLOC_FREE(ctx);
2886                 return WERR_NOMEM;
2887         }
2888
2889         get_local_printer_publishing_data(ctx, &mods, pdata);
2890         ads_mod_str(ctx, &mods, SPOOL_REG_PRINTERNAME, printer);
2891
2892         /* publish it */
2893         ads_rc = ads_mod_printer_entry(ads, prt_dn, ctx, &mods);
2894         if (ads_rc.err.rc == LDAP_NO_SUCH_OBJECT) {
2895                 int i;
2896                 for (i=0; mods[i] != 0; i++)
2897                         ;
2898                 mods[i] = (LDAPMod *)-1;
2899                 ads_rc = ads_add_printer_entry(ads, prt_dn, ctx, &mods);
2900         }
2901
2902         if (!ADS_ERR_OK(ads_rc)) {
2903                 DEBUG(3, ("error publishing %s: %s\n",
2904                           printer, ads_errstr(ads_rc)));
2905         }
2906
2907         /* retreive the guid and store it locally */
2908         if (ADS_ERR_OK(ads_search_dn(ads, &res, prt_dn, attrs))) {
2909                 ZERO_STRUCT(guid);
2910                 ads_pull_guid(ads, res, &guid);
2911                 ads_msgfree(ads, res);
2912                 store_printer_guid(printer, guid);
2913         }
2914         TALLOC_FREE(ctx);
2915
2916         return win_rc;
2917 }
2918
2919 static WERROR nt_printer_unpublish_ads(ADS_STRUCT *ads,
2920                                        const char *printer)
2921 {
2922         ADS_STATUS ads_rc;
2923         LDAPMessage *res = NULL;
2924         char *prt_dn = NULL;
2925
2926         DEBUG(5, ("unpublishing printer %s\n", printer));
2927
2928         /* remove the printer from the directory */
2929         ads_rc = ads_find_printer_on_server(ads, &res,
2930                                             printer, global_myname());
2931
2932         if (ADS_ERR_OK(ads_rc) && res && ads_count_replies(ads, res)) {
2933                 prt_dn = ads_get_dn(ads, talloc_tos(), res);
2934                 if (!prt_dn) {
2935                         ads_msgfree(ads, res);
2936                         return WERR_NOMEM;
2937                 }
2938                 ads_rc = ads_del_dn(ads, prt_dn);
2939                 TALLOC_FREE(prt_dn);
2940         }
2941
2942         if (res) {
2943                 ads_msgfree(ads, res);
2944         }
2945         return WERR_OK;
2946 }
2947
2948 /****************************************************************************
2949  * Publish a printer in the directory
2950  *
2951  * @param mem_ctx      memory context
2952  * @param server_info  server_info to access winreg pipe
2953  * @param pinfo2       printer information
2954  * @param action       publish/unpublish action
2955  * @return WERROR indicating status of publishing
2956  ***************************************************************************/
2957
2958 WERROR nt_printer_publish(TALLOC_CTX *mem_ctx,
2959                           struct auth_serversupplied_info *server_info,
2960                           struct spoolss_PrinterInfo2 *pinfo2,
2961                           int action)
2962 {
2963         uint32_t info2_mask = SPOOLSS_PRINTER_INFO_ATTRIBUTES;
2964         struct spoolss_SetPrinterInfo2 *sinfo2;
2965         ADS_STATUS ads_rc;
2966         ADS_STRUCT *ads = NULL;
2967         WERROR win_rc;
2968
2969         sinfo2 = talloc_zero(mem_ctx, struct spoolss_SetPrinterInfo2);
2970         if (!sinfo2) {
2971                 return WERR_NOMEM;
2972         }
2973
2974         switch (action) {
2975         case DSPRINT_PUBLISH:
2976         case DSPRINT_UPDATE:
2977                 pinfo2->attributes |= PRINTER_ATTRIBUTE_PUBLISHED;
2978                 break;
2979         case DSPRINT_UNPUBLISH:
2980                 pinfo2->attributes ^= PRINTER_ATTRIBUTE_PUBLISHED;
2981                 break;
2982         default:
2983                 win_rc = WERR_NOT_SUPPORTED;
2984                 goto done;
2985         }
2986
2987         sinfo2->attributes = pinfo2->attributes;
2988
2989         win_rc = winreg_update_printer(mem_ctx, server_info,
2990                                         pinfo2->sharename, info2_mask,
2991                                         sinfo2, NULL, NULL);
2992         if (!W_ERROR_IS_OK(win_rc)) {
2993                 DEBUG(3, ("err %d saving data\n", W_ERROR_V(win_rc)));
2994                 goto done;
2995         }
2996
2997         TALLOC_FREE(sinfo2);
2998
2999         ads = ads_init(lp_realm(), lp_workgroup(), NULL);
3000         if (!ads) {
3001                 DEBUG(3, ("ads_init() failed\n"));
3002                 win_rc = WERR_SERVER_UNAVAILABLE;
3003                 goto done;
3004         }
3005         setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
3006         SAFE_FREE(ads->auth.password);
3007         ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
3008                 NULL, NULL);
3009
3010         /* ads_connect() will find the DC for us */
3011         ads_rc = ads_connect(ads);
3012         if (!ADS_ERR_OK(ads_rc)) {
3013                 DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
3014                 win_rc = WERR_ACCESS_DENIED;
3015                 goto done;
3016         }
3017
3018         switch (action) {
3019         case DSPRINT_PUBLISH:
3020         case DSPRINT_UPDATE:
3021                 win_rc = nt_printer_publish_ads(ads, pinfo2);
3022                 break;
3023         case DSPRINT_UNPUBLISH:
3024                 win_rc = nt_printer_unpublish_ads(ads, pinfo2->sharename);
3025                 break;
3026         }
3027
3028 done:
3029         ads_destroy(&ads);
3030         return win_rc;
3031 }
3032
3033 WERROR check_published_printers(void)
3034 {
3035         ADS_STATUS ads_rc;
3036         ADS_STRUCT *ads = NULL;
3037         int snum;
3038         int n_services = lp_numservices();
3039         TALLOC_CTX *tmp_ctx = NULL;
3040         struct auth_serversupplied_info *server_info = NULL;
3041         struct spoolss_PrinterInfo2 *pinfo2;
3042         NTSTATUS status;
3043         WERROR result;
3044
3045         tmp_ctx = talloc_new(NULL);
3046         if (!tmp_ctx) return WERR_NOMEM;
3047
3048         ads = ads_init(lp_realm(), lp_workgroup(), NULL);
3049         if (!ads) {
3050                 DEBUG(3, ("ads_init() failed\n"));
3051                 return WERR_SERVER_UNAVAILABLE;
3052         }
3053         setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
3054         SAFE_FREE(ads->auth.password);
3055         ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
3056                 NULL, NULL);
3057
3058         /* ads_connect() will find the DC for us */
3059         ads_rc = ads_connect(ads);
3060         if (!ADS_ERR_OK(ads_rc)) {
3061                 DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
3062                 result = WERR_ACCESS_DENIED;
3063                 goto done;
3064         }
3065
3066         status = make_server_info_system(tmp_ctx, &server_info);
3067         if (!NT_STATUS_IS_OK(status)) {
3068                 DEBUG(0, ("check_published_printers: "
3069                           "Could not create system server_info\n"));
3070                 result = WERR_ACCESS_DENIED;
3071                 goto done;
3072         }
3073
3074         for (snum = 0; snum < n_services; snum++) {
3075                 if (!lp_snum_ok(snum) || !lp_print_ok(snum)) {
3076                         continue;
3077                 }
3078
3079                 result = winreg_get_printer(tmp_ctx, server_info, NULL,
3080                                             lp_servicename(snum), &pinfo2);
3081                 if (!W_ERROR_IS_OK(result)) {
3082                         continue;
3083                 }
3084
3085                 if (pinfo2->attributes & PRINTER_ATTRIBUTE_PUBLISHED) {
3086                         nt_printer_publish_ads(ads, pinfo2);
3087                 }
3088
3089                 TALLOC_FREE(pinfo2);
3090         }
3091
3092         result = WERR_OK;
3093 done:
3094         ads_destroy(&ads);
3095         ads_kdestroy("MEMORY:prtpub_cache");
3096         talloc_free(tmp_ctx);
3097         return result;
3098 }
3099
3100 bool is_printer_published(TALLOC_CTX *mem_ctx,
3101                           struct auth_serversupplied_info *server_info,
3102                           char *servername, char *printer, struct GUID *guid,
3103                           struct spoolss_PrinterInfo2 **info2)
3104 {
3105         struct spoolss_PrinterInfo2 *pinfo2 = NULL;
3106         enum winreg_Type type;
3107         uint8_t *data;
3108         uint32_t data_size;
3109         WERROR result;
3110         NTSTATUS status;
3111
3112         result = winreg_get_printer(mem_ctx, server_info,
3113                                     servername, printer, &pinfo2);
3114         if (!W_ERROR_IS_OK(result)) {
3115                 return false;
3116         }
3117
3118         if (!(pinfo2->attributes & PRINTER_ATTRIBUTE_PUBLISHED)) {
3119                 TALLOC_FREE(pinfo2);
3120                 return false;
3121         }
3122
3123         if (!guid) {
3124                 goto done;
3125         }
3126
3127         /* fetching printer guids really ought to be a separate function. */
3128
3129         result = winreg_get_printer_dataex(mem_ctx, server_info, printer,
3130                                            SPOOL_DSSPOOLER_KEY, "objectGUID",
3131                                            &type, &data, &data_size);
3132         if (!W_ERROR_IS_OK(result)) {
3133                 TALLOC_FREE(pinfo2);
3134                 return false;
3135         }
3136
3137         /* We used to store the guid as REG_BINARY, then swapped
3138            to REG_SZ for Vista compatibility so check for both */
3139
3140         switch (type) {
3141         case REG_SZ:
3142                 status = GUID_from_string((char *)data, guid);
3143                 if (!NT_STATUS_IS_OK(status)) {
3144                         TALLOC_FREE(pinfo2);
3145                         return false;
3146                 }
3147                 break;
3148
3149         case REG_BINARY:
3150                 if (data_size != sizeof(struct GUID)) {
3151                         TALLOC_FREE(pinfo2);
3152                         return false;
3153                 }
3154                 memcpy(guid, data, sizeof(struct GUID));
3155                 break;
3156         default:
3157                 DEBUG(0,("is_printer_published: GUID value stored as "
3158                          "invaluid type (%d)\n", type));
3159                 break;
3160         }
3161
3162 done:
3163         if (info2) {
3164                 *info2 = talloc_move(mem_ctx, &pinfo2);
3165         }
3166         talloc_free(pinfo2);
3167         return true;
3168 }
3169 #else
3170 WERROR nt_printer_publish(TALLOC_CTX *mem_ctx,
3171                           struct auth_serversupplied_info *server_info,
3172                           struct spoolss_PrinterInfo2 *pinfo2,
3173                           int action)
3174 {
3175         return WERR_OK;
3176 }
3177
3178 WERROR check_published_printers(void)
3179 {
3180         return WERR_OK;
3181 }
3182
3183 bool is_printer_published(TALLOC_CTX *mem_ctx,
3184                           struct auth_serversupplied_info *server_info,
3185                           char *servername, char *printer, struct GUID *guid,
3186                           struct spoolss_PrinterInfo2 **info2)
3187 {
3188         return False;
3189 }
3190 #endif /* HAVE_ADS */
3191
3192 /****************************************************************************
3193  ***************************************************************************/
3194
3195 WERROR delete_all_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key )
3196 {
3197         NT_PRINTER_DATA *data;
3198         int             i;
3199         int             removed_keys = 0;
3200         int             empty_slot;
3201
3202         data = p2->data;
3203         empty_slot = data->num_keys;
3204
3205         if ( !key )
3206                 return WERR_INVALID_PARAM;
3207
3208         /* remove all keys */
3209
3210         if ( !strlen(key) ) {
3211
3212                 TALLOC_FREE( data );
3213
3214                 p2->data = NULL;
3215
3216                 DEBUG(8,("delete_all_printer_data: Removed all Printer Data from printer [%s]\n",
3217                         p2->printername ));
3218
3219                 return WERR_OK;
3220         }
3221
3222         /* remove a specific key (and all subkeys) */
3223
3224         for ( i=0; i<data->num_keys; i++ ) {
3225                 if ( StrnCaseCmp( data->keys[i].name, key, strlen(key)) == 0 ) {
3226                         DEBUG(8,("delete_all_printer_data: Removed all Printer Data from key [%s]\n",
3227                                 data->keys[i].name));
3228
3229                         TALLOC_FREE( data->keys[i].name );
3230                         TALLOC_FREE( data->keys[i].values );
3231
3232                         /* mark the slot as empty */
3233
3234                         ZERO_STRUCTP( &data->keys[i] );
3235                 }
3236         }
3237
3238         /* find the first empty slot */
3239
3240         for ( i=0; i<data->num_keys; i++ ) {
3241                 if ( !data->keys[i].name ) {
3242                         empty_slot = i;
3243                         removed_keys++;
3244                         break;
3245                 }
3246         }
3247
3248         if ( i == data->num_keys )
3249                 /* nothing was removed */
3250                 return WERR_INVALID_PARAM;
3251
3252         /* move everything down */
3253
3254         for ( i=empty_slot+1; i<data->num_keys; i++ ) {
3255                 if ( data->keys[i].name ) {
3256                         memcpy( &data->keys[empty_slot], &data->keys[i], sizeof(NT_PRINTER_KEY) );
3257                         ZERO_STRUCTP( &data->keys[i] );
3258                         empty_slot++;
3259                         removed_keys++;
3260                 }
3261         }
3262
3263         /* update count */
3264
3265         data->num_keys -= removed_keys;
3266
3267         /* sanity check to see if anything is left */
3268
3269         if ( !data->num_keys ) {
3270                 DEBUG(8,("delete_all_printer_data: No keys left for printer [%s]\n", p2->printername ));
3271
3272                 SAFE_FREE( data->keys );
3273                 ZERO_STRUCTP( data );
3274         }
3275
3276         return WERR_OK;
3277 }
3278
3279 /****************************************************************************
3280  ***************************************************************************/
3281
3282 WERROR delete_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value )
3283 {
3284         WERROR          result = WERR_OK;
3285         int             key_index;
3286
3287         /* we must have names on non-zero length */
3288
3289         if ( !key || !*key|| !value || !*value )
3290                 return WERR_INVALID_NAME;
3291
3292         /* find the printer key first */
3293
3294         key_index = lookup_printerkey( p2->data, key );
3295         if ( key_index == -1 )
3296                 return WERR_OK;
3297
3298         /* make sure the value exists so we can return the correct error code */
3299
3300         if ( !regval_ctr_getvalue( p2->data->keys[key_index].values, value ) )
3301                 return WERR_BADFILE;
3302
3303         regval_ctr_delvalue( p2->data->keys[key_index].values, value );
3304
3305         DEBUG(8,("delete_printer_data: Removed key => [%s], value => [%s]\n",
3306                 key, value ));
3307
3308         return result;
3309 }
3310
3311 /****************************************************************************
3312  ***************************************************************************/
3313
3314 WERROR add_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value,
3315                            uint32 type, uint8 *data, int real_len )
3316 {
3317         WERROR          result = WERR_OK;
3318         int             key_index;
3319
3320         /* we must have names on non-zero length */
3321
3322         if ( !key || !*key|| !value || !*value )
3323                 return WERR_INVALID_NAME;
3324
3325         /* find the printer key first */
3326
3327         key_index = lookup_printerkey( p2->data, key );
3328         if ( key_index == -1 )
3329                 key_index = add_new_printer_key( p2->data, key );
3330
3331         if ( key_index == -1 )
3332                 return WERR_NOMEM;
3333
3334         regval_ctr_addvalue( p2->data->keys[key_index].values, value,
3335                 type, data, real_len );
3336
3337         DEBUG(8,("add_printer_data: Added key => [%s], value => [%s], type=> [%d], size => [%d]\n",
3338                 key, value, type, real_len  ));
3339
3340         return result;
3341 }
3342
3343 /****************************************************************************
3344  ***************************************************************************/
3345
3346 struct regval_blob* get_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value )
3347 {
3348         int             key_index;
3349
3350         if ( (key_index = lookup_printerkey( p2->data, key )) == -1 )
3351                 return NULL;
3352
3353         DEBUG(8,("get_printer_data: Attempting to lookup key => [%s], value => [%s]\n",
3354                 key, value ));
3355
3356         return regval_ctr_getvalue( p2->data->keys[key_index].values, value );
3357 }
3358
3359 /****************************************************************************
3360  Unpack a list of registry values frem the TDB
3361  ***************************************************************************/
3362
3363 static int unpack_values(NT_PRINTER_DATA *printer_data, const uint8 *buf, int buflen)
3364 {
3365         int             len = 0;
3366         uint32          type;
3367         fstring string;
3368         const char *valuename = NULL;
3369         const char *keyname = NULL;
3370         char            *str;
3371         int             size;
3372         uint8           *data_p;
3373         struct regval_blob      *regval_p;
3374         int             key_index;
3375
3376         /* add the "PrinterDriverData" key first for performance reasons */
3377
3378         add_new_printer_key( printer_data, SPOOL_PRINTERDATA_KEY );
3379
3380         /* loop and unpack the rest of the registry values */
3381
3382         while ( True ) {
3383
3384                 /* check to see if there are any more registry values */
3385
3386                 regval_p = NULL;
3387                 len += tdb_unpack(buf+len, buflen-len, "p", &regval_p);
3388                 if ( !regval_p )
3389                         break;
3390
3391                 /* unpack the next regval */
3392
3393                 len += tdb_unpack(buf+len, buflen-len, "fdB",
3394                                   string,
3395                                   &type,
3396                                   &size,
3397                                   &data_p);
3398
3399                 /* lookup for subkey names which have a type of REG_NONE */
3400                 /* there's no data with this entry */
3401
3402                 if ( type == REG_NONE ) {
3403                         if ( (key_index=lookup_printerkey( printer_data, string)) == -1 )
3404                                 add_new_printer_key( printer_data, string );
3405                         continue;
3406                 }
3407
3408                 /*
3409                  * break of the keyname from the value name.
3410                  * Valuenames can have embedded '\'s so be careful.
3411                  * only support one level of keys.  See the
3412                  * "Konica Fiery S300 50C-K v1.1. enu" 2k driver.
3413                  * -- jerry
3414                  */
3415
3416                 str = strchr_m( string, '\\');
3417
3418                 /* Put in "PrinterDriverData" is no key specified */
3419
3420                 if ( !str ) {
3421                         keyname = SPOOL_PRINTERDATA_KEY;
3422                         valuename = string;
3423                 }
3424                 else {
3425                         *str = '\0';
3426                         keyname = string;
3427                         valuename = str+1;
3428                 }
3429
3430                 /* see if we need a new key */
3431
3432                 if ( (key_index=lookup_printerkey( printer_data, keyname )) == -1 )
3433                         key_index = add_new_printer_key( printer_data, keyname );
3434
3435                 if ( key_index == -1 ) {
3436                         DEBUG(0,("unpack_values: Failed to allocate a new key [%s]!\n",
3437                                 keyname));
3438                         break;
3439                 }
3440
3441                 DEBUG(8,("specific: [%s:%s], len: %d\n", keyname, valuename, size));
3442
3443                 /* Vista doesn't like unknown REG_BINARY values in DsSpooler.
3444                    Thanks to Martin Zielinski for the hint. */
3445
3446                 if ( type == REG_BINARY &&
3447                      strequal( keyname, SPOOL_DSSPOOLER_KEY ) &&
3448                      strequal( valuename, "objectGUID" ) )
3449                 {
3450                         struct GUID guid;
3451
3452                         /* convert the GUID to a UNICODE string */
3453
3454                         memcpy( &guid, data_p, sizeof(struct GUID) );
3455
3456                         regval_ctr_addvalue_sz(printer_data->keys[key_index].values,
3457                                                valuename,
3458                                                GUID_string(talloc_tos(), &guid));
3459
3460                 } else {
3461                         /* add the value */
3462
3463                         regval_ctr_addvalue( printer_data->keys[key_index].values,
3464                                              valuename, type, data_p,
3465                                              size );
3466                 }
3467
3468                 SAFE_FREE(data_p); /* 'B' option to tdbpack does a malloc() */
3469
3470         }
3471
3472         return len;
3473 }
3474
3475 /****************************************************************************
3476  ***************************************************************************/
3477
3478 static char *win_driver;
3479 static char *os2_driver;
3480
3481 static const char *get_win_driver(void)
3482 {
3483         if (win_driver == NULL) {
3484                 return "";
3485         }
3486         return win_driver;
3487 }
3488
3489 static const char *get_os2_driver(void)
3490 {
3491         if (os2_driver == NULL) {
3492                 return "";
3493         }
3494         return os2_driver;
3495 }
3496
3497 static bool set_driver_mapping(const char *from, const char *to)
3498 {
3499         SAFE_FREE(win_driver);
3500         SAFE_FREE(os2_driver);
3501
3502         win_driver = SMB_STRDUP(from);
3503         os2_driver = SMB_STRDUP(to);
3504
3505         if (win_driver == NULL || os2_driver == NULL) {
3506                 SAFE_FREE(win_driver);
3507                 SAFE_FREE(os2_driver);
3508                 return false;
3509         }
3510         return true;
3511 }
3512
3513 static void map_to_os2_driver(fstring drivername)
3514 {
3515         char *mapfile = lp_os2_driver_map();
3516         char **lines = NULL;
3517         int numlines = 0;
3518         int i;
3519
3520         if (!strlen(drivername))
3521                 return;
3522
3523         if (!*mapfile)
3524                 return;
3525
3526         if (strequal(drivername, get_win_driver())) {
3527                 DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",
3528                         drivername, get_os2_driver()));
3529                 fstrcpy(drivername, get_os2_driver());
3530                 return;
3531         }
3532
3533         lines = file_lines_load(mapfile, &numlines,0,NULL);
3534         if (numlines == 0 || lines == NULL) {
3535                 DEBUG(0,("No entries in OS/2 driver map %s\n",mapfile));
3536                 TALLOC_FREE(lines);
3537                 return;
3538         }
3539
3540         DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile));
3541
3542         for( i = 0; i < numlines; i++) {
3543                 char *nt_name = lines[i];
3544                 char *os2_name = strchr(nt_name,'=');
3545
3546                 if (!os2_name)
3547                         continue;
3548
3549                 *os2_name++ = 0;
3550
3551                 while (isspace(*nt_name))
3552                         nt_name++;
3553
3554                 if (!*nt_name || strchr("#;",*nt_name))
3555                         continue;
3556
3557                 {
3558                         int l = strlen(nt_name);
3559                         while (l && isspace(nt_name[l-1])) {
3560                                 nt_name[l-1] = 0;
3561                                 l--;
3562                         }
3563                 }
3564
3565                 while (isspace(*os2_name))
3566                         os2_name++;
3567
3568                 {
3569                         int l = strlen(os2_name);
3570                         while (l && isspace(os2_name[l-1])) {
3571                                 os2_name[l-1] = 0;
3572                                 l--;
3573                         }
3574                 }
3575
3576                 if (strequal(nt_name,drivername)) {
3577                         DEBUG(3,("Mapped windows driver %s to os2 driver%s\n",drivername,os2_name));
3578                         set_driver_mapping(drivername,os2_name);
3579                         fstrcpy(drivername,os2_name);
3580                         TALLOC_FREE(lines);
3581                         return;
3582                 }
3583         }
3584
3585         TALLOC_FREE(lines);
3586 }
3587
3588 /**
3589  * @internal
3590  *
3591  * @brief Map a Windows driver to a OS/2 driver.
3592  *
3593  * @param[in]  mem_ctx  The memory context to use.
3594  *
3595  * @param[in,out] pdrivername The drivername of Windows to remap.
3596  *
3597  * @return              WERR_OK on success, a corresponding WERROR on failure.
3598  */
3599 WERROR spoolss_map_to_os2_driver(TALLOC_CTX *mem_ctx, const char **pdrivername)
3600 {
3601         const char *mapfile = lp_os2_driver_map();
3602         char **lines = NULL;
3603         const char *drivername;
3604         int numlines = 0;
3605         int i;
3606
3607         if (pdrivername == NULL || *pdrivername == NULL || *pdrivername[0] == '\0') {
3608                 return WERR_INVALID_PARAMETER;
3609         }
3610
3611         drivername = *pdrivername;
3612
3613         if (mapfile[0] == '\0') {
3614                 return WERR_BADFILE;
3615         }
3616
3617         if (strequal(drivername, get_win_driver())) {
3618                 DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",
3619                         drivername, get_os2_driver()));
3620                 drivername = talloc_strdup(mem_ctx, get_os2_driver());
3621                 if (drivername == NULL) {
3622                         return WERR_NOMEM;
3623                 }
3624                 *pdrivername = drivername;
3625                 return WERR_OK;
3626         }
3627
3628         lines = file_lines_load(mapfile, &numlines, 0, NULL);
3629         if (numlines == 0 || lines == NULL) {
3630                 DEBUG(0,("No entries in OS/2 driver map %s\n", mapfile));
3631                 TALLOC_FREE(lines);
3632                 return WERR_EMPTY;
3633         }
3634
3635         DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile));
3636
3637         for( i = 0; i < numlines; i++) {
3638                 char *nt_name = lines[i];
3639                 char *os2_name = strchr(nt_name, '=');
3640
3641                 if (os2_name == NULL) {
3642                         continue;
3643                 }
3644
3645                 *os2_name++ = '\0';
3646
3647                 while (isspace(*nt_name)) {
3648                         nt_name++;
3649                 }
3650
3651                 if (*nt_name == '\0' || strchr("#;", *nt_name)) {
3652                         continue;
3653                 }
3654
3655                 {
3656                         int l = strlen(nt_name);
3657                         while (l && isspace(nt_name[l - 1])) {
3658                                 nt_name[l - 1] = 0;
3659                                 l--;
3660                         }
3661                 }
3662
3663                 while (isspace(*os2_name)) {
3664                         os2_name++;
3665                 }
3666
3667                 {
3668                         int l = strlen(os2_name);
3669                         while (l && isspace(os2_name[l-1])) {
3670                                 os2_name[l-1] = 0;
3671                                 l--;
3672                         }
3673                 }
3674
3675                 if (strequal(nt_name, drivername)) {
3676                         DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",drivername,os2_name));
3677                         set_driver_mapping(drivername, os2_name);
3678                         drivername = talloc_strdup(mem_ctx, os2_name);
3679                         TALLOC_FREE(lines);
3680                         if (drivername == NULL) {
3681                                 return WERR_NOMEM;
3682                         }
3683                         *pdrivername = drivername;
3684                         return WERR_OK;
3685                 }
3686         }
3687
3688         TALLOC_FREE(lines);
3689         return WERR_OK;
3690 }
3691
3692 /****************************************************************************
3693  Get a default printer info 2 struct.
3694 ****************************************************************************/
3695
3696 static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 *info,
3697                                 const char *servername,
3698                                 const char* sharename,
3699                                 bool get_loc_com)
3700 {
3701         int snum = lp_servicenumber(sharename);
3702         WERROR result;
3703
3704         slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", servername);
3705         slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
3706                 servername, sharename);
3707         fstrcpy(info->sharename, sharename);
3708         fstrcpy(info->portname, SAMBA_PRINTER_PORT_NAME);
3709
3710         /* by setting the driver name to an empty string, a local NT admin
3711            can now run the **local** APW to install a local printer driver
3712            for a Samba shared printer in 2.2.  Without this, drivers **must** be
3713            installed on the Samba server for NT clients --jerry */
3714 #if 0   /* JERRY --do not uncomment-- */
3715         if (!*info->drivername)
3716                 fstrcpy(info->drivername, "NO DRIVER AVAILABLE FOR THIS PRINTER");
3717 #endif
3718
3719
3720         DEBUG(10,("get_a_printer_2_default: driver name set to [%s]\n", info->drivername));
3721
3722         strlcpy(info->comment, "", sizeof(info->comment));
3723         fstrcpy(info->printprocessor, "winprint");
3724         fstrcpy(info->datatype, "RAW");
3725
3726 #ifdef HAVE_CUPS
3727         if (get_loc_com && (enum printing_types)lp_printing(snum) == PRINT_CUPS ) {
3728                 /* Pull the location and comment strings from cups if we don't
3729                    already have one */
3730                 if ( !strlen(info->location) || !strlen(info->comment) ) {
3731                         char *comment = NULL;
3732                         char *location = NULL;
3733                         if (cups_pull_comment_location(info, info->sharename,
3734                                                        &comment, &location)) {
3735                                 strlcpy(info->comment, comment, sizeof(info->comment));
3736                                 fstrcpy(info->location, location);
3737                                 TALLOC_FREE(comment);
3738                                 TALLOC_FREE(location);
3739                         }
3740                 }
3741         }
3742 #endif
3743
3744         info->attributes = PRINTER_ATTRIBUTE_SAMBA;
3745
3746         info->starttime = 0; /* Minutes since 12:00am GMT */
3747         info->untiltime = 0; /* Minutes since 12:00am GMT */
3748         info->priority = 1;
3749         info->default_priority = 1;
3750         info->setuptime = (uint32)time(NULL);
3751
3752         /*
3753          * I changed this as I think it is better to have a generic
3754          * DEVMODE than to crash Win2k explorer.exe   --jerry
3755          * See the HP Deskjet 990c Win2k drivers for an example.
3756          *
3757          * However the default devmode appears to cause problems
3758          * with the HP CLJ 8500 PCL driver.  Hence the addition of
3759          * the "default devmode" parameter   --jerry 22/01/2002
3760          */
3761
3762         if (lp_default_devmode(snum)) {
3763                 result = spoolss_create_default_devmode(info,
3764                                                         info->printername,
3765                                                         &info->devmode);
3766                 if (!W_ERROR_IS_OK(result)) {
3767                         goto fail;
3768                 }
3769         } else {
3770                 info->devmode = NULL;
3771         }
3772
3773         if (!nt_printing_getsec(info, sharename, &info->secdesc_buf)) {
3774                 goto fail;
3775         }
3776
3777         info->data = TALLOC_ZERO_P(info, NT_PRINTER_DATA);
3778         if (!info->data) {
3779                 goto fail;
3780         }
3781
3782         add_new_printer_key(info->data, SPOOL_PRINTERDATA_KEY);
3783
3784         return WERR_OK;
3785
3786 fail:
3787         TALLOC_FREE(info->devmode);
3788
3789         return WERR_ACCESS_DENIED;
3790 }
3791
3792 /****************************************************************************
3793 ****************************************************************************/
3794
3795 static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info,
3796                                 const char *servername,
3797                                 const char *sharename,
3798                                 bool get_loc_com)
3799 {
3800         int len = 0;
3801         int snum = lp_servicenumber(sharename);
3802         TDB_DATA kbuf, dbuf;
3803         fstring printername;
3804         char *comment = NULL;
3805         WERROR result;
3806
3807         kbuf = make_printer_tdbkey(talloc_tos(), sharename);
3808
3809         dbuf = tdb_fetch(tdb_printers, kbuf);
3810         if (!dbuf.dptr) {
3811                 return get_a_printer_2_default(info, servername,
3812                                         sharename, get_loc_com);
3813         }
3814
3815         len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff",
3816                         &info->attributes,
3817                         &info->priority,
3818                         &info->default_priority,
3819                         &info->starttime,
3820                         &info->untiltime,
3821                         &info->status,
3822                         &info->cjobs,
3823                         &info->averageppm,
3824                         &info->changeid,
3825                         &info->c_setprinter,
3826                         &info->setuptime,
3827                         info->servername,
3828                         info->printername,
3829                         info->sharename,
3830                         info->portname,
3831                         info->drivername,
3832                         &comment,
3833                         info->location,
3834                         info->sepfile,
3835                         info->printprocessor,
3836                         info->datatype,
3837                         info->parameters);
3838
3839         if (comment) {
3840                 strlcpy(info->comment, comment, sizeof(info->comment));
3841                 SAFE_FREE(comment);
3842         }
3843
3844         /* Samba has to have shared raw drivers. */
3845         info->attributes |= PRINTER_ATTRIBUTE_SAMBA;
3846         info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
3847
3848         /* Restore the stripped strings. */
3849         slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", servername);
3850
3851         if ( lp_force_printername(snum) ) {
3852                 slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", servername, sharename );
3853         } else {
3854                 slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", servername, info->printername);
3855         }
3856
3857         fstrcpy(info->printername, printername);
3858
3859 #ifdef HAVE_CUPS
3860         if (get_loc_com && (enum printing_types)lp_printing(snum) == PRINT_CUPS ) {
3861                 /* Pull the location and comment strings from cups if we don't
3862                    already have one */
3863                 if ( !strlen(info->location) || !strlen(info->comment) ) {
3864                         char *location = NULL;
3865                         comment = NULL;
3866                         if (cups_pull_comment_location(info, info->sharename,
3867                                                        &comment, &location)) {
3868                                 strlcpy(info->comment, comment, sizeof(info->comment));
3869                                 fstrcpy(info->location, location);
3870                                 TALLOC_FREE(comment);
3871                                 TALLOC_FREE(location);
3872                         }
3873                 }
3874         }
3875 #endif
3876
3877         len += unpack_devicemode(info, dbuf.dptr+len,
3878                                         dbuf.dsize-len,
3879                                         &info->devmode);
3880
3881         /*
3882          * Some client drivers freak out if there is a NULL devmode
3883          * (probably the driver is not checking before accessing
3884          * the devmode pointer)   --jerry
3885          *
3886          * See comments in get_a_printer_2_default()
3887          */
3888
3889         if (lp_default_devmode(snum) && !info->devmode) {
3890                 DEBUG(8,("get_a_printer_2: Constructing a default device mode for [%s]\n",
3891                         printername));
3892                 result = spoolss_create_default_devmode(info, printername,
3893                                                         &info->devmode);
3894                 if (!W_ERROR_IS_OK(result)) {
3895                         goto done;
3896                 }
3897         }
3898
3899         if (info->devmode) {
3900                 info->devmode->devicename = talloc_strdup(info->devmode,
3901                                                           info->printername);
3902                 if (!info->devmode->devicename) {
3903                         result = WERR_NOMEM;
3904                         goto done;
3905                 }
3906         }
3907
3908         if ( !(info->data = TALLOC_ZERO_P( info, NT_PRINTER_DATA )) ) {
3909                 DEBUG(0,("unpack_values: talloc() failed!\n"));
3910                 result = WERR_NOMEM;
3911                 goto done;
3912         }
3913         len += unpack_values( info->data, dbuf.dptr+len, dbuf.dsize-len );
3914
3915         /* This will get the current RPC talloc context, but we should be
3916            passing this as a parameter... fixme... JRA ! */
3917
3918         if (!nt_printing_getsec(info, sharename, &info->secdesc_buf)) {
3919                 result = WERR_NOMEM;
3920                 goto done;
3921         }
3922
3923         /* Fix for OS/2 drivers. */
3924
3925         if (get_remote_arch() == RA_OS2) {
3926                 map_to_os2_driver(info->drivername);
3927         }
3928
3929         DEBUG(9,("Unpacked printer [%s] name [%s] running driver [%s]\n",
3930                  sharename, info->printername, info->drivername));
3931
3932         result = WERR_OK;
3933
3934 done:
3935         SAFE_FREE(dbuf.dptr);
3936         return result;
3937 }
3938
3939 /****************************************************************************
3940  Debugging function, dump at level 6 the struct in the logs.
3941 ****************************************************************************/
3942 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
3943 {
3944         uint32 result;
3945         NT_PRINTER_INFO_LEVEL_2 *info2;
3946
3947         DEBUG(106,("Dumping printer at level [%d]\n", level));
3948
3949         switch (level) {
3950                 case 2:
3951                 {
3952                         if (printer->info_2 == NULL)
3953                                 result=5;
3954                         else
3955                         {
3956                                 info2=printer->info_2;
3957
3958                                 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
3959                                 DEBUGADD(106,("priority:[%d]\n", info2->priority));
3960                                 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
3961                                 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
3962                                 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
3963                                 DEBUGADD(106,("status:[%d]\n", info2->status));
3964                                 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
3965                                 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
3966                                 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
3967                                 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
3968                                 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
3969
3970                                 DEBUGADD(106,("servername:[%s]\n", info2->servername));
3971                                 DEBUGADD(106,("printername:[%s]\n", info2->printername));
3972                                 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
3973                                 DEBUGADD(106,("portname:[%s]\n", info2->portname));
3974                                 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
3975                                 DEBUGADD(106,("comment:[%s]\n", info2->comment));
3976                                 DEBUGADD(106,("location:[%s]\n", info2->location));
3977                                 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
3978                                 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
3979                                 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
3980                                 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
3981                                 result=0;
3982                         }
3983                         break;
3984                 }
3985                 default:
3986                         DEBUGADD(106,("dump_a_printer: Level %u not implemented\n", (unsigned int)level ));
3987                         result=1;
3988                         break;
3989         }
3990
3991         return result;
3992 }
3993
3994 /****************************************************************************
3995  Update the changeid time.
3996  This is SO NASTY as some drivers need this to change, others need it
3997  static. This value will change every second, and I must hope that this
3998  is enough..... DON'T CHANGE THIS CODE WITHOUT A TEST MATRIX THE SIZE OF
3999  UTAH ! JRA.
4000 ****************************************************************************/
4001
4002 static uint32 rev_changeid(void)
4003 {
4004         struct timeval tv;
4005
4006         get_process_uptime(&tv);
4007
4008 #if 1   /* JERRY */
4009         /* Return changeid as msec since spooler restart */
4010         return tv.tv_sec * 1000 + tv.tv_usec / 1000;
4011 #else
4012         /*
4013          * This setting seems to work well but is too untested
4014          * to replace the above calculation.  Left in for experiementation
4015          * of the reader            --jerry (Tue Mar 12 09:15:05 CST 2002)
4016          */
4017         return tv.tv_sec * 10 + tv.tv_usec / 100000;
4018 #endif
4019 }
4020
4021
4022 /*
4023  * The function below are the high level ones.
4024  * only those ones must be called from the spoolss code.
4025  * JFM.
4026  */
4027
4028 /****************************************************************************
4029  Modify a printer. This is called from SETPRINTERDATA/DELETEPRINTERDATA.
4030 ****************************************************************************/
4031
4032 WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
4033 {
4034         WERROR result;
4035
4036         dump_a_printer(printer, level);
4037
4038         switch (level) {
4039                 case 2:
4040                 {
4041                         /*
4042                          * Update the changestamp.  Emperical tests show that the
4043                          * ChangeID is always updated,but c_setprinter is
4044                          *  global spooler variable (not per printer).
4045                          */
4046
4047                         /* ChangeID **must** be increasing over the lifetime
4048                            of client's spoolss service in order for the
4049                            client's cache to show updates */
4050
4051                         printer->info_2->changeid = rev_changeid();
4052
4053                         /*
4054                          * Because one day someone will ask:
4055                          * NT->NT       An admin connection to a remote
4056                          *              printer show changes imeediately in
4057                          *              the properities dialog
4058                          *
4059                          *              A non-admin connection will only show the
4060                          *              changes after viewing the properites page
4061                          *              2 times.  Seems to be related to a
4062                          *              race condition in the client between the spooler
4063                          *              updating the local cache and the Explorer.exe GUI
4064                          *              actually displaying the properties.
4065                          *
4066                          *              This is fixed in Win2k.  admin/non-admin
4067                          *              connections both display changes immediately.
4068                          *
4069                          * 14/12/01     --jerry
4070                          */
4071
4072                         result=update_a_printer_2(printer->info_2);
4073                         break;
4074                 }
4075                 default:
4076                         result=WERR_UNKNOWN_LEVEL;
4077                         break;
4078         }
4079
4080         return result;
4081 }
4082
4083 /****************************************************************************
4084  Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
4085
4086  Previously the code had a memory allocation problem because it always
4087  used the TALLOC_CTX from the Printer_entry*.   This context lasts
4088  as a long as the original handle is open.  So if the client made a lot
4089  of getprinter[data]() calls, the memory usage would climb.  Now we use
4090  a short lived TALLOC_CTX for printer_info_2 objects returned.  We
4091  still use the Printer_entry->ctx for maintaining the cache copy though
4092  since that object must live as long as the handle by definition.
4093                                                     --jerry
4094
4095 ****************************************************************************/
4096
4097 static WERROR get_a_printer_internal( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level,
4098                         const char *sharename, bool get_loc_com)
4099 {
4100         WERROR result;
4101         fstring servername;
4102
4103         DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
4104
4105         if ( !(*pp_printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) {
4106                 DEBUG(0,("get_a_printer: talloc() fail.\n"));
4107                 return WERR_NOMEM;
4108         }
4109
4110         switch (level) {
4111                 case 2:
4112                         if ( !((*pp_printer)->info_2 = TALLOC_ZERO_P(*pp_printer, NT_PRINTER_INFO_LEVEL_2)) ) {
4113                                 DEBUG(0,("get_a_printer: talloc() fail.\n"));
4114                                 TALLOC_FREE( *pp_printer );
4115                                 return WERR_NOMEM;
4116                         }
4117
4118                         if ( print_hnd )
4119                                 fstrcpy( servername, print_hnd->servername );
4120                         else {
4121                                 fstrcpy( servername, "%L" );
4122                                 standard_sub_basic( "", "", servername,
4123                                                     sizeof(servername)-1 );
4124                         }
4125
4126                         result = get_a_printer_2( (*pp_printer)->info_2,
4127                                         servername, sharename, get_loc_com);
4128
4129                         /* we have a new printer now.  Save it with this handle */
4130
4131                         if ( !W_ERROR_IS_OK(result) ) {
4132                                 TALLOC_FREE( *pp_printer );
4133                                 DEBUG(10,("get_a_printer: [%s] level %u returning %s\n",
4134                                         sharename, (unsigned int)level, win_errstr(result)));
4135                                 return result;
4136                         }
4137
4138                         dump_a_printer( *pp_printer, level);
4139
4140                         break;
4141
4142                 default:
4143                         TALLOC_FREE( *pp_printer );
4144                         return WERR_UNKNOWN_LEVEL;
4145         }
4146
4147         return WERR_OK;
4148 }
4149
4150 WERROR get_a_printer( Printer_entry *print_hnd,
4151                         NT_PRINTER_INFO_LEVEL **pp_printer,
4152                         uint32 level,
4153                         const char *sharename)
4154 {
4155         return get_a_printer_internal(print_hnd, pp_printer, level,
4156                                         sharename, true);
4157 }
4158
4159 WERROR get_a_printer_search( Printer_entry *print_hnd,
4160                         NT_PRINTER_INFO_LEVEL **pp_printer,
4161                         uint32 level,
4162                         const char *sharename)
4163 {
4164         return get_a_printer_internal(print_hnd, pp_printer, level,
4165                                         sharename, false);
4166 }
4167
4168 /****************************************************************************
4169  Deletes a NT_PRINTER_INFO_LEVEL struct.
4170 ****************************************************************************/
4171
4172 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
4173 {
4174         NT_PRINTER_INFO_LEVEL *printer = *pp_printer;
4175
4176         if ( !printer )
4177                 return 0;
4178
4179         switch (level) {
4180                 case 2:
4181                         TALLOC_FREE(printer->info_2);
4182                         break;
4183
4184                 default:
4185                         DEBUG(0,("free_a_printer: unknown level! [%d]\n", level ));
4186                         return 1;
4187         }
4188
4189         TALLOC_FREE(*pp_printer);
4190
4191         return 0;
4192 }
4193
4194 /****************************************************************************
4195 ****************************************************************************/
4196
4197 bool driver_info_ctr_to_info8(struct spoolss_AddDriverInfoCtr *r,
4198                               struct spoolss_DriverInfo8 *_info8)
4199 {
4200         struct spoolss_DriverInfo8 info8;
4201
4202         ZERO_STRUCT(info8);
4203
4204         switch (r->level) {
4205         case 3:
4206                 info8.version           = r->info.info3->version;
4207                 info8.driver_name       = r->info.info3->driver_name;
4208                 info8.architecture      = r->info.info3->architecture;
4209                 info8.driver_path       = r->info.info3->driver_path;
4210                 info8.data_file         = r->info.info3->data_file;
4211                 info8.config_file       = r->info.info3->config_file;
4212                 info8.help_file         = r->info.info3->help_file;
4213                 info8.monitor_name      = r->info.info3->monitor_name;
4214                 info8.default_datatype  = r->info.info3->default_datatype;
4215                 if (r->info.info3->dependent_files && r->info.info3->dependent_files->string) {
4216                         info8.dependent_files   = r->info.info3->dependent_files->string;
4217                 }
4218                 break;
4219         case 6:
4220                 info8.version           = r->info.info6->version;
4221                 info8.driver_name       = r->info.info6->driver_name;
4222                 info8.architecture      = r->info.info6->architecture;
4223                 info8.driver_path       = r->info.info6->driver_path;
4224                 info8.data_file         = r->info.info6->data_file;
4225                 info8.config_file       = r->info.info6->config_file;
4226                 info8.help_file         = r->info.info6->help_file;
4227                 info8.monitor_name      = r->info.info6->monitor_name;
4228                 info8.default_datatype  = r->info.info6->default_datatype;
4229                 if (r->info.info6->dependent_files && r->info.info6->dependent_files->string) {
4230                         info8.dependent_files   = r->info.info6->dependent_files->string;
4231                 }
4232                 info8.driver_date       = r->info.info6->driver_date;
4233                 info8.driver_version    = r->info.info6->driver_version;
4234                 info8.manufacturer_name = r->info.info6->manufacturer_name;
4235                 info8.manufacturer_url  = r->info.info6->manufacturer_url;
4236                 info8.hardware_id       = r->info.info6->hardware_id;
4237                 info8.provider          = r->info.info6->provider;
4238                 break;
4239         case 8:
4240                 info8.version           = r->info.info8->version;
4241                 info8.driver_name       = r->info.info8->driver_name;
4242                 info8.architecture      = r->info.info8->architecture;
4243                 info8.driver_path       = r->info.info8->driver_path;
4244                 info8.data_file         = r->info.info8->data_file;
4245                 info8.config_file       = r->info.info8->config_file;
4246                 info8.help_file         = r->info.info8->help_file;
4247                 info8.monitor_name      = r->info.info8->monitor_name;
4248                 info8.default_datatype  = r->info.info8->default_datatype;
4249                 if (r->info.info8->dependent_files && r->info.info8->dependent_files->string) {
4250                         info8.dependent_files   = r->info.info8->dependent_files->string;
4251                 }
4252                 if (r->info.info8->previous_names && r->info.info8->previous_names->string) {
4253                         info8.previous_names    = r->info.info8->previous_names->string;
4254                 }
4255                 info8.driver_date       = r->info.info8->driver_date;
4256                 info8.driver_version    = r->info.info8->driver_version;
4257                 info8.manufacturer_name = r->info.info8->manufacturer_name;
4258                 info8.manufacturer_url  = r->info.info8->manufacturer_url;
4259                 info8.hardware_id       = r->info.info8->hardware_id;
4260                 info8.provider          = r->info.info8->provider;
4261                 info8.print_processor   = r->info.info8->print_processor;
4262                 info8.vendor_setup      = r->info.info8->vendor_setup;
4263                 if (r->info.info8->color_profiles && r->info.info8->color_profiles->string) {
4264                         info8.color_profiles = r->info.info8->color_profiles->string;
4265                 }
4266                 info8.inf_path          = r->info.info8->inf_path;
4267                 info8.printer_driver_attributes = r->info.info8->printer_driver_attributes;
4268                 if (r->info.info8->core_driver_dependencies && r->info.info8->core_driver_dependencies->string) {
4269                         info8.core_driver_dependencies = r->info.info8->core_driver_dependencies->string;
4270                 }
4271                 info8.min_inbox_driver_ver_date = r->info.info8->min_inbox_driver_ver_date;
4272                 info8.min_inbox_driver_ver_version = r->info.info8->min_inbox_driver_ver_version;
4273                 break;
4274         default:
4275                 return false;
4276         }
4277
4278         *_info8 = info8;
4279
4280         return true;
4281 }
4282
4283
4284 /****************************************************************************
4285   Determine whether or not a particular driver is currently assigned
4286   to a printer
4287 ****************************************************************************/
4288
4289 bool printer_driver_in_use(TALLOC_CTX *mem_ctx,
4290                            struct auth_serversupplied_info *server_info,
4291                            const struct spoolss_DriverInfo8 *r)
4292 {
4293         int snum;
4294         int n_services = lp_numservices();
4295         bool in_use = False;
4296         struct spoolss_PrinterInfo2 *pinfo2 = NULL;
4297         WERROR result;
4298
4299         if (!r) {
4300                 return false;
4301         }
4302
4303         DEBUG(10,("printer_driver_in_use: Beginning search through ntprinters.tdb...\n"));
4304
4305         /* loop through the printers.tdb and check for the drivername */
4306
4307         for (snum=0; snum<n_services && !in_use; snum++) {
4308                 if (!lp_snum_ok(snum) || !lp_print_ok(snum)) {
4309                         continue;
4310                 }
4311
4312                 result = winreg_get_printer(mem_ctx, server_info, NULL,
4313                                             lp_servicename(snum), &pinfo2);
4314                 if (!W_ERROR_IS_OK(result)) {
4315                         continue; /* skip */
4316                 }
4317
4318                 if (strequal(r->driver_name, pinfo2->drivername)) {
4319                         in_use = True;
4320                 }
4321
4322                 TALLOC_FREE(pinfo2);
4323         }
4324
4325         DEBUG(10,("printer_driver_in_use: Completed search through ntprinters.tdb...\n"));
4326
4327         if ( in_use ) {
4328                 struct spoolss_DriverInfo8 *driver;
4329                 WERROR werr;
4330
4331                 DEBUG(5,("printer_driver_in_use: driver \"%s\" is currently in use\n", r->driver_name));
4332
4333                 /* we can still remove the driver if there is one of
4334                    "Windows NT x86" version 2 or 3 left */
4335
4336                 if (!strequal("Windows NT x86", r->architecture)) {
4337                         werr = winreg_get_driver(mem_ctx, server_info,
4338                                                  "Windows NT x86",
4339                                                  r->driver_name,
4340                                                  DRIVER_ANY_VERSION,
4341                                                  &driver);
4342                 } else if (r->version == 2) {
4343                         werr = winreg_get_driver(mem_ctx, server_info,
4344                                                  "Windows NT x86",
4345                                                  r->driver_name,
4346                                                  3, &driver);
4347                 } else if (r->version == 3) {
4348                         werr = winreg_get_driver(mem_ctx, server_info,
4349                                                  "Windows NT x86",
4350                                                  r->driver_name,
4351                                                  2, &driver);
4352                 } else {
4353                         DEBUG(0, ("printer_driver_in_use: ERROR!"
4354                                   " unknown driver version (%d)\n",
4355                                   r->version));
4356                         werr = WERR_UNKNOWN_PRINTER_DRIVER;
4357                 }
4358
4359                 /* now check the error code */
4360
4361                 if ( W_ERROR_IS_OK(werr) ) {
4362                         /* it's ok to remove the driver, we have other architctures left */
4363                         in_use = False;
4364                         talloc_free(driver);
4365                 }
4366         }
4367
4368         /* report that the driver is not in use by default */
4369
4370         return in_use;
4371 }
4372
4373
4374 /**********************************************************************
4375  Check to see if a ogiven file is in use by *info
4376  *********************************************************************/
4377
4378 static bool drv_file_in_use(const char *file, const struct spoolss_DriverInfo8 *info)
4379 {
4380         int i = 0;
4381
4382         if ( !info )
4383                 return False;
4384
4385         /* mz: skip files that are in the list but already deleted */
4386         if (!file || !file[0]) {
4387                 return false;
4388         }
4389
4390         if (strequal(file, info->driver_path))
4391                 return True;
4392
4393         if (strequal(file, info->data_file))
4394                 return True;
4395
4396         if (strequal(file, info->config_file))
4397                 return True;
4398
4399         if (strequal(file, info->help_file))
4400                 return True;
4401
4402         /* see of there are any dependent files to examine */
4403
4404         if (!info->dependent_files)
4405                 return False;
4406
4407         while (info->dependent_files[i] && *info->dependent_files[i]) {
4408                 if (strequal(file, info->dependent_files[i]))
4409                         return True;
4410                 i++;
4411         }
4412
4413         return False;
4414
4415 }
4416
4417 /**********************************************************************
4418  Utility function to remove the dependent file pointed to by the
4419  input parameter from the list
4420  *********************************************************************/
4421
4422 static void trim_dependent_file(TALLOC_CTX *mem_ctx, const char **files, int idx)
4423 {
4424
4425         /* bump everything down a slot */
4426
4427         while (files && files[idx+1]) {
4428                 files[idx] = talloc_strdup(mem_ctx, files[idx+1]);
4429                 idx++;
4430         }
4431
4432         files[idx] = NULL;
4433
4434         return;
4435 }
4436
4437 /**********************************************************************
4438  Check if any of the files used by src are also used by drv
4439  *********************************************************************/
4440
4441 static bool trim_overlap_drv_files(TALLOC_CTX *mem_ctx,
4442                                    struct spoolss_DriverInfo8 *src,
4443                                    const struct spoolss_DriverInfo8 *drv)
4444 {
4445         bool    in_use = False;
4446         int     i = 0;
4447
4448         if ( !src || !drv )
4449                 return False;
4450
4451         /* check each file.  Remove it from the src structure if it overlaps */
4452
4453         if (drv_file_in_use(src->driver_path, drv)) {
4454                 in_use = True;
4455                 DEBUG(10,("Removing driverfile [%s] from list\n", src->driver_path));
4456                 src->driver_path = talloc_strdup(mem_ctx, "");
4457                 if (!src->driver_path) { return false; }
4458         }
4459
4460         if (drv_file_in_use(src->data_file, drv)) {
4461                 in_use = True;
4462                 DEBUG(10,("Removing datafile [%s] from list\n", src->data_file));
4463                 src->data_file = talloc_strdup(mem_ctx, "");
4464                 if (!src->data_file) { return false; }
4465         }
4466
4467         if (drv_file_in_use(src->config_file, drv)) {
4468                 in_use = True;
4469                 DEBUG(10,("Removing configfile [%s] from list\n", src->config_file));
4470                 src->config_file = talloc_strdup(mem_ctx, "");
4471                 if (!src->config_file) { return false; }
4472         }
4473
4474         if (drv_file_in_use(src->help_file, drv)) {
4475                 in_use = True;
4476                 DEBUG(10,("Removing helpfile [%s] from list\n", src->help_file));
4477                 src->help_file = talloc_strdup(mem_ctx, "");
4478                 if (!src->help_file) { return false; }
4479         }
4480
4481         /* are there any dependentfiles to examine? */
4482
4483         if (!src->dependent_files)
4484                 return in_use;
4485
4486         while (src->dependent_files[i] && *src->dependent_files[i]) {
4487                 if (drv_file_in_use(src->dependent_files[i], drv)) {
4488                         in_use = True;
4489                         DEBUG(10,("Removing [%s] from dependent file list\n", src->dependent_files[i]));
4490                         trim_dependent_file(mem_ctx, src->dependent_files, i);
4491                 } else
4492                         i++;
4493         }
4494
4495         return in_use;
4496 }
4497
4498 /****************************************************************************
4499   Determine whether or not a particular driver files are currently being
4500   used by any other driver.
4501
4502   Return value is True if any files were in use by other drivers
4503   and False otherwise.
4504
4505   Upon return, *info has been modified to only contain the driver files
4506   which are not in use
4507
4508   Fix from mz:
4509
4510   This needs to check all drivers to ensure that all files in use
4511   have been removed from *info, not just the ones in the first
4512   match.
4513 ****************************************************************************/
4514
4515 bool printer_driver_files_in_use(TALLOC_CTX *mem_ctx,
4516                                  struct auth_serversupplied_info *server_info,
4517                                  struct spoolss_DriverInfo8 *info)
4518 {
4519         int                             i;
4520         uint32                          version;
4521         struct spoolss_DriverInfo8      *driver;
4522         bool in_use = false;
4523         uint32_t num_drivers;
4524         const char **drivers;
4525         WERROR result;
4526
4527         if ( !info )
4528                 return False;
4529
4530         version = info->version;
4531
4532         /* loop over all driver versions */
4533
4534         DEBUG(5,("printer_driver_files_in_use: Beginning search of drivers...\n"));
4535
4536         /* get the list of drivers */
4537
4538         result = winreg_get_driver_list(mem_ctx, server_info,
4539                                         info->architecture, version,
4540                                         &num_drivers, &drivers);
4541         if (!W_ERROR_IS_OK(result)) {
4542                 return true;
4543         }
4544
4545         DEBUGADD(4, ("we have:[%d] drivers in environment [%s] and version [%d]\n",
4546                      num_drivers, info->architecture, version));
4547
4548         /* check each driver for overlap in files */
4549
4550         for (i = 0; i < num_drivers; i++) {
4551                 DEBUGADD(5,("\tdriver: [%s]\n", drivers[i]));
4552
4553                 driver = NULL;
4554
4555                 result = winreg_get_driver(mem_ctx, server_info,
4556                                            info->architecture, drivers[i],
4557                                            version, &driver);
4558                 if (!W_ERROR_IS_OK(result)) {
4559                         talloc_free(drivers);
4560                         return True;
4561                 }
4562
4563                 /* check if d2 uses any files from d1 */
4564                 /* only if this is a different driver than the one being deleted */
4565
4566                 if (!strequal(info->driver_name, driver->driver_name)) {
4567                         if (trim_overlap_drv_files(mem_ctx, info, driver)) {
4568                                 /* mz: Do not instantly return -
4569                                  * we need to ensure this file isn't
4570                                  * also in use by other drivers. */
4571                                 in_use = true;
4572                         }
4573                 }
4574
4575                 talloc_free(driver);
4576         }
4577
4578         talloc_free(drivers);
4579
4580         DEBUG(5,("printer_driver_files_in_use: Completed search of drivers...\n"));
4581
4582         return in_use;
4583 }
4584
4585 static NTSTATUS driver_unlink_internals(connection_struct *conn,
4586                                         const char *name)
4587 {
4588         struct smb_filename *smb_fname = NULL;
4589         NTSTATUS status;
4590
4591         status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL,
4592             &smb_fname);
4593         if (!NT_STATUS_IS_OK(status)) {
4594                 return status;
4595         }
4596
4597         status = unlink_internals(conn, NULL, 0, smb_fname, false);
4598
4599         TALLOC_FREE(smb_fname);
4600         return status;
4601 }
4602
4603 /****************************************************************************
4604   Actually delete the driver files.  Make sure that
4605   printer_driver_files_in_use() return False before calling
4606   this.
4607 ****************************************************************************/
4608
4609 bool delete_driver_files(struct auth_serversupplied_info *server_info,
4610                          const struct spoolss_DriverInfo8 *r)
4611 {
4612         int i = 0;
4613         char *s;
4614         const char *file;
4615         connection_struct *conn;
4616         NTSTATUS nt_status;
4617         char *oldcwd;
4618         fstring printdollar;
4619         int printdollar_snum;
4620         bool ret = false;
4621
4622         if (!r) {
4623                 return false;
4624         }
4625
4626         DEBUG(6,("delete_driver_files: deleting driver [%s] - version [%d]\n",
4627                 r->driver_name, r->version));
4628
4629         fstrcpy(printdollar, "print$");
4630
4631         printdollar_snum = find_service(printdollar);
4632         if (printdollar_snum == -1) {
4633                 return false;
4634         }
4635
4636         nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum,
4637                                        lp_pathname(printdollar_snum),
4638                                        server_info, &oldcwd);
4639         if (!NT_STATUS_IS_OK(nt_status)) {
4640                 DEBUG(0,("delete_driver_files: create_conn_struct "
4641                          "returned %s\n", nt_errstr(nt_status)));
4642                 return false;
4643         }
4644
4645         if ( !CAN_WRITE(conn) ) {
4646                 DEBUG(3,("delete_driver_files: Cannot delete print driver when [print$] is read-only\n"));
4647                 goto fail;
4648         }
4649
4650         /* now delete the files; must strip the '\print$' string from
4651            fron of path                                                */
4652
4653         if (r->driver_path && r->driver_path[0]) {
4654                 if ((s = strchr(&r->driver_path[1], '\\')) != NULL) {
4655                         file = s;
4656                         DEBUG(10,("deleting driverfile [%s]\n", s));
4657                         driver_unlink_internals(conn, file);
4658                 }
4659         }
4660
4661         if (r->config_file && r->config_file[0]) {
4662                 if ((s = strchr(&r->config_file[1], '\\')) != NULL) {
4663                         file = s;
4664                         DEBUG(10,("deleting configfile [%s]\n", s));
4665                         driver_unlink_internals(conn, file);
4666                 }
4667         }
4668
4669         if (r->data_file && r->data_file[0]) {
4670                 if ((s = strchr(&r->data_file[1], '\\')) != NULL) {
4671                         file = s;
4672                         DEBUG(10,("deleting datafile [%s]\n", s));
4673                         driver_unlink_internals(conn, file);
4674                 }
4675         }
4676
4677         if (r->help_file && r->help_file[0]) {
4678                 if ((s = strchr(&r->help_file[1], '\\')) != NULL) {
4679                         file = s;
4680                         DEBUG(10,("deleting helpfile [%s]\n", s));
4681                         driver_unlink_internals(conn, file);
4682                 }
4683         }
4684
4685         /* check if we are done removing files */
4686
4687         if (r->dependent_files) {
4688                 while (r->dependent_files[i] && r->dependent_files[i][0]) {
4689                         char *p;
4690
4691                         /* bypass the "\print$" portion of the path */
4692
4693                         if ((p = strchr(r->dependent_files[i]+1, '\\')) != NULL) {
4694                                 file = p;
4695                                 DEBUG(10,("deleting dependent file [%s]\n", file));
4696                                 driver_unlink_internals(conn, file);
4697                         }
4698
4699                         i++;
4700                 }
4701         }
4702
4703         goto done;
4704  fail:
4705         ret = false;
4706  done:
4707         if (conn != NULL) {
4708                 vfs_ChDir(conn, oldcwd);
4709                 conn_free(conn);
4710         }
4711         return ret;
4712 }
4713
4714 /****************************************************************************
4715  Store a security desc for a printer.
4716 ****************************************************************************/
4717
4718 WERROR nt_printing_setsec(const char *sharename, struct sec_desc_buf *secdesc_ctr)
4719 {
4720         struct sec_desc_buf *new_secdesc_ctr = NULL;
4721         struct sec_desc_buf *old_secdesc_ctr = NULL;
4722         TALLOC_CTX *mem_ctx = NULL;
4723         TDB_DATA kbuf;
4724         TDB_DATA dbuf;
4725         DATA_BLOB blob;
4726         WERROR status;
4727         NTSTATUS nt_status;
4728
4729         mem_ctx = talloc_init("nt_printing_setsec");
4730         if (mem_ctx == NULL)
4731                 return WERR_NOMEM;
4732
4733         /* The old owner and group sids of the security descriptor are not
4734            present when new ACEs are added or removed by changing printer
4735            permissions through NT.  If they are NULL in the new security
4736            descriptor then copy them over from the old one. */
4737
4738         if (!secdesc_ctr->sd->owner_sid || !secdesc_ctr->sd->group_sid) {
4739                 struct dom_sid *owner_sid, *group_sid;
4740                 struct security_acl *dacl, *sacl;
4741                 struct security_descriptor *psd = NULL;
4742                 size_t size;
4743
4744                 if (!nt_printing_getsec(mem_ctx, sharename, &old_secdesc_ctr)) {
4745                         status = WERR_NOMEM;
4746                         goto out;
4747                 }
4748
4749                 /* Pick out correct owner and group sids */
4750
4751                 owner_sid = secdesc_ctr->sd->owner_sid ?
4752                         secdesc_ctr->sd->owner_sid :
4753                         old_secdesc_ctr->sd->owner_sid;
4754
4755                 group_sid = secdesc_ctr->sd->group_sid ?
4756                         secdesc_ctr->sd->group_sid :
4757                         old_secdesc_ctr->sd->group_sid;
4758
4759                 dacl = secdesc_ctr->sd->dacl ?
4760                         secdesc_ctr->sd->dacl :
4761                         old_secdesc_ctr->sd->dacl;
4762
4763                 sacl = secdesc_ctr->sd->sacl ?
4764                         secdesc_ctr->sd->sacl :
4765                         old_secdesc_ctr->sd->sacl;
4766
4767                 /* Make a deep copy of the security descriptor */
4768
4769                 psd = make_sec_desc(mem_ctx, secdesc_ctr->sd->revision, secdesc_ctr->sd->type,
4770                                     owner_sid, group_sid,
4771                                     sacl,
4772                                     dacl,
4773                                     &size);
4774
4775                 if (!psd) {
4776                         status = WERR_NOMEM;
4777                         goto out;
4778                 }
4779
4780                 new_secdesc_ctr = make_sec_desc_buf(mem_ctx, size, psd);
4781         }
4782
4783         if (!new_secdesc_ctr) {
4784                 new_secdesc_ctr = secdesc_ctr;
4785         }
4786
4787         /* Store the security descriptor in a tdb */
4788
4789         nt_status = marshall_sec_desc_buf(mem_ctx, new_secdesc_ctr,
4790                                           &blob.data, &blob.length);
4791         if (!NT_STATUS_IS_OK(nt_status)) {
4792                 status = ntstatus_to_werror(nt_status);
4793                 goto out;
4794         }
4795
4796         kbuf = make_printers_secdesc_tdbkey(mem_ctx, sharename );
4797
4798         dbuf.dptr = (unsigned char *)blob.data;
4799         dbuf.dsize = blob.length;
4800
4801         if (tdb_trans_store(tdb_printers, kbuf, dbuf, TDB_REPLACE)==0) {
4802                 status = WERR_OK;
4803         } else {
4804                 DEBUG(1,("Failed to store secdesc for %s\n", sharename));
4805                 status = WERR_BADFUNC;
4806         }
4807
4808         /* Free malloc'ed memory */
4809         talloc_free(blob.data);
4810
4811  out:
4812
4813         if (mem_ctx)
4814                 talloc_destroy(mem_ctx);
4815         return status;
4816 }
4817
4818 /****************************************************************************
4819  Construct a default security descriptor buffer for a printer.
4820 ****************************************************************************/
4821
4822 static struct sec_desc_buf *construct_default_printer_sdb(TALLOC_CTX *ctx)
4823 {
4824         struct security_ace ace[7];     /* max number of ace entries */
4825         int i = 0;
4826         uint32_t sa;
4827         struct security_acl *psa = NULL;
4828         struct sec_desc_buf *sdb = NULL;
4829         struct security_descriptor *psd = NULL;
4830         struct dom_sid adm_sid;
4831         size_t sd_size;
4832
4833         /* Create an ACE where Everyone is allowed to print */
4834
4835         sa = PRINTER_ACE_PRINT;
4836         init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
4837                      sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
4838
4839         /* Add the domain admins group if we are a DC */
4840
4841         if ( IS_DC ) {
4842                 struct dom_sid domadmins_sid;
4843
4844                 sid_compose(&domadmins_sid, get_global_sam_sid(),
4845                             DOMAIN_RID_ADMINS);
4846
4847                 sa = PRINTER_ACE_FULL_CONTROL;
4848                 init_sec_ace(&ace[i++], &domadmins_sid,
4849                         SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
4850                         SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
4851                 init_sec_ace(&ace[i++], &domadmins_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
4852                         sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
4853         }
4854         else if (secrets_fetch_domain_sid(lp_workgroup(), &adm_sid)) {
4855                 sid_append_rid(&adm_sid, DOMAIN_RID_ADMINISTRATOR);
4856
4857                 sa = PRINTER_ACE_FULL_CONTROL;
4858                 init_sec_ace(&ace[i++], &adm_sid,
4859                         SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
4860                         SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
4861                 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
4862                         sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
4863         }
4864
4865         /* add BUILTIN\Administrators as FULL CONTROL */
4866
4867         sa = PRINTER_ACE_FULL_CONTROL;
4868         init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
4869                 SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
4870                 SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
4871         init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
4872                 SEC_ACE_TYPE_ACCESS_ALLOWED,
4873                 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
4874
4875         /* add BUILTIN\Print Operators as FULL CONTROL */
4876
4877         sa = PRINTER_ACE_FULL_CONTROL;
4878         init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
4879                 SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
4880                 SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
4881         init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
4882                 SEC_ACE_TYPE_ACCESS_ALLOWED,
4883                 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
4884
4885         /* Make the security descriptor owned by the BUILTIN\Administrators */
4886
4887         /* The ACL revision number in rpc_secdesc.h differs from the one
4888            created by NT when setting ACE entries in printer
4889            descriptors.  NT4 complains about the property being edited by a
4890            NT5 machine. */
4891
4892         if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) != NULL) {
4893                 psd = make_sec_desc(ctx, SD_REVISION, SEC_DESC_SELF_RELATIVE,
4894                         &global_sid_Builtin_Administrators,
4895                         &global_sid_Builtin_Administrators,
4896                         NULL, psa, &sd_size);
4897         }
4898
4899         if (!psd) {
4900                 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
4901                 return NULL;
4902         }
4903
4904         sdb = make_sec_desc_buf(ctx, sd_size, psd);
4905
4906         DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
4907                  (unsigned int)sd_size));
4908
4909         return sdb;
4910 }
4911
4912 /****************************************************************************
4913  Get a security desc for a printer.
4914 ****************************************************************************/
4915
4916 bool nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, struct sec_desc_buf **secdesc_ctr)
4917 {
4918         TDB_DATA kbuf;
4919         TDB_DATA dbuf;
4920         DATA_BLOB blob;
4921         char *temp;
4922         NTSTATUS status;
4923
4924         if (strlen(sharename) > 2 && (temp = strchr(sharename + 2, '\\'))) {
4925                 sharename = temp + 1;
4926         }
4927
4928         /* Fetch security descriptor from tdb */
4929
4930         kbuf = make_printers_secdesc_tdbkey(ctx, sharename);
4931
4932         dbuf = tdb_fetch(tdb_printers, kbuf);
4933         if (dbuf.dptr) {
4934
4935                 status = unmarshall_sec_desc_buf(ctx, dbuf.dptr, dbuf.dsize,
4936                                                  secdesc_ctr);
4937                 SAFE_FREE(dbuf.dptr);
4938
4939                 if (NT_STATUS_IS_OK(status)) {
4940                         return true;
4941                 }
4942         }
4943
4944         *secdesc_ctr = construct_default_printer_sdb(ctx);
4945         if (!*secdesc_ctr) {
4946                 return false;
4947         }
4948
4949         status = marshall_sec_desc_buf(ctx, *secdesc_ctr,
4950                                        &blob.data, &blob.length);
4951         if (NT_STATUS_IS_OK(status)) {
4952                 dbuf.dptr = (unsigned char *)blob.data;
4953                 dbuf.dsize = blob.length;
4954                 tdb_trans_store(tdb_printers, kbuf, dbuf, TDB_REPLACE);
4955                 talloc_free(blob.data);
4956         }
4957
4958         /* If security descriptor is owned by S-1-1-0 and winbindd is up,
4959            this security descriptor has been created when winbindd was
4960            down.  Take ownership of security descriptor. */
4961
4962         if (sid_equal((*secdesc_ctr)->sd->owner_sid, &global_sid_World)) {
4963                 struct dom_sid owner_sid;
4964
4965                 /* Change sd owner to workgroup administrator */
4966
4967                 if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid)) {
4968                         struct sec_desc_buf *new_secdesc_ctr = NULL;
4969                         struct security_descriptor *psd = NULL;
4970                         size_t size;
4971
4972                         /* Create new sd */
4973
4974                         sid_append_rid(&owner_sid, DOMAIN_RID_ADMINISTRATOR);
4975
4976                         psd = make_sec_desc(ctx, (*secdesc_ctr)->sd->revision, (*secdesc_ctr)->sd->type,
4977                                             &owner_sid,
4978                                             (*secdesc_ctr)->sd->group_sid,
4979                                             (*secdesc_ctr)->sd->sacl,
4980                                             (*secdesc_ctr)->sd->dacl,
4981                                             &size);
4982
4983                         if (!psd) {
4984                                 return False;
4985                         }
4986
4987                         new_secdesc_ctr = make_sec_desc_buf(ctx, size, psd);
4988                         if (!new_secdesc_ctr) {
4989                                 return False;
4990                         }
4991
4992                         /* Swap with other one */
4993
4994                         *secdesc_ctr = new_secdesc_ctr;
4995
4996                         /* Set it */
4997
4998                         nt_printing_setsec(sharename, *secdesc_ctr);
4999                 }
5000         }
5001
5002         if (DEBUGLEVEL >= 10) {
5003                 struct security_acl *the_acl = (*secdesc_ctr)->sd->dacl;
5004                 int i;
5005
5006                 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
5007                            sharename, the_acl->num_aces));
5008
5009                 for (i = 0; i < the_acl->num_aces; i++) {
5010                         DEBUG(10, ("%s %d %d 0x%08x\n",
5011                                    sid_string_dbg(&the_acl->aces[i].trustee),
5012                                    the_acl->aces[i].type, the_acl->aces[i].flags,
5013                                    the_acl->aces[i].access_mask));
5014                 }
5015         }
5016
5017         return True;
5018 }
5019
5020 /* error code:
5021         0: everything OK
5022         1: level not implemented
5023         2: file doesn't exist
5024         3: can't allocate memory
5025         4: can't free memory
5026         5: non existant struct
5027 */
5028
5029 /*
5030         A printer and a printer driver are 2 different things.
5031         NT manages them separatelly, Samba does the same.
5032         Why ? Simply because it's easier and it makes sense !
5033
5034         Now explanation: You have 3 printers behind your samba server,
5035         2 of them are the same make and model (laser A and B). But laser B
5036         has an 3000 sheet feeder and laser A doesn't such an option.
5037         Your third printer is an old dot-matrix model for the accounting :-).
5038
5039         If the /usr/local/samba/lib directory (default dir), you will have
5040         5 files to describe all of this.
5041
5042         3 files for the printers (1 by printer):
5043                 NTprinter_laser A
5044                 NTprinter_laser B
5045                 NTprinter_accounting
5046         2 files for the drivers (1 for the laser and 1 for the dot matrix)
5047                 NTdriver_printer model X
5048                 NTdriver_printer model Y
5049
5050 jfm: I should use this comment for the text file to explain
5051         same thing for the forms BTW.
5052         Je devrais mettre mes commentaires en francais, ca serait mieux :-)
5053
5054 */
5055
5056 /* Convert generic access rights to printer object specific access rights.
5057    It turns out that NT4 security descriptors use generic access rights and
5058    NT5 the object specific ones. */
5059
5060 void map_printer_permissions(struct security_descriptor *sd)
5061 {
5062         int i;
5063
5064         for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
5065                 se_map_generic(&sd->dacl->aces[i].access_mask,
5066                                &printer_generic_mapping);
5067         }
5068 }
5069
5070 void map_job_permissions(struct security_descriptor *sd)
5071 {
5072         int i;
5073
5074         for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
5075                 se_map_generic(&sd->dacl->aces[i].access_mask,
5076                                &job_generic_mapping);
5077         }
5078 }
5079
5080
5081 /****************************************************************************
5082  Check a user has permissions to perform the given operation.  We use the
5083  permission constants defined in include/rpc_spoolss.h to check the various
5084  actions we perform when checking printer access.
5085
5086    PRINTER_ACCESS_ADMINISTER:
5087        print_queue_pause, print_queue_resume, update_printer_sec,
5088        update_printer, spoolss_addprinterex_level_2,
5089        _spoolss_setprinterdata
5090
5091    PRINTER_ACCESS_USE:
5092        print_job_start
5093
5094    JOB_ACCESS_ADMINISTER:
5095        print_job_delete, print_job_pause, print_job_resume,
5096        print_queue_purge
5097
5098   Try access control in the following order (for performance reasons):
5099     1)  root and SE_PRINT_OPERATOR can do anything (easy check)
5100     2)  check security descriptor (bit comparisons in memory)
5101     3)  "printer admins" (may result in numerous calls to winbind)
5102
5103  ****************************************************************************/
5104 bool print_access_check(struct auth_serversupplied_info *server_info, int snum,
5105                         int access_type)
5106 {
5107         struct spoolss_security_descriptor *secdesc = NULL;
5108         uint32 access_granted;
5109         size_t sd_size;
5110         NTSTATUS status;
5111         WERROR result;
5112         const char *pname;
5113         TALLOC_CTX *mem_ctx = NULL;
5114         SE_PRIV se_printop = SE_PRINT_OPERATOR;
5115
5116         /* If user is NULL then use the current_user structure */
5117
5118         /* Always allow root or SE_PRINT_OPERATROR to do anything */
5119
5120         if (server_info->utok.uid == sec_initial_uid()
5121             || user_has_privileges(server_info->ptok, &se_printop ) ) {
5122                 return True;
5123         }
5124
5125         /* Get printer name */
5126
5127         pname = lp_printername(snum);
5128
5129         if (!pname || !*pname) {
5130                 errno = EACCES;
5131                 return False;
5132         }
5133
5134         /* Get printer security descriptor */
5135
5136         if(!(mem_ctx = talloc_init("print_access_check"))) {
5137                 errno = ENOMEM;
5138                 return False;
5139         }
5140
5141         result = winreg_get_printer_secdesc(mem_ctx,
5142                                             server_info,
5143                                             pname,
5144                                             &secdesc);
5145         if (!W_ERROR_IS_OK(result)) {
5146                 talloc_destroy(mem_ctx);
5147                 errno = ENOMEM;
5148                 return False;
5149         }
5150
5151         if (access_type == JOB_ACCESS_ADMINISTER) {
5152                 struct spoolss_security_descriptor *parent_secdesc = secdesc;
5153
5154                 /* Create a child security descriptor to check permissions
5155                    against.  This is because print jobs are child objects
5156                    objects of a printer. */
5157                 status = se_create_child_secdesc(mem_ctx,
5158                                                  &secdesc,
5159                                                  &sd_size,
5160                                                  parent_secdesc,
5161                                                  parent_secdesc->owner_sid,
5162                                                  parent_secdesc->group_sid,
5163                                                  false);
5164                 if (!NT_STATUS_IS_OK(status)) {
5165                         talloc_destroy(mem_ctx);
5166                         errno = map_errno_from_nt_status(status);
5167                         return False;
5168                 }
5169
5170                 map_job_permissions(secdesc);
5171         } else {
5172                 map_printer_permissions(secdesc);
5173         }
5174
5175         /* Check access */
5176         status = se_access_check(secdesc, server_info->ptok, access_type,
5177                                  &access_granted);
5178
5179         DEBUG(4, ("access check was %s\n", NT_STATUS_IS_OK(status) ? "SUCCESS" : "FAILURE"));
5180
5181         /* see if we need to try the printer admin list */
5182
5183         if (!NT_STATUS_IS_OK(status) &&
5184             (token_contains_name_in_list(uidtoname(server_info->utok.uid),
5185                                          server_info->info3->base.domain.string,
5186                                          NULL, server_info->ptok,
5187                                          lp_printer_admin(snum)))) {
5188                 talloc_destroy(mem_ctx);
5189                 return True;
5190         }
5191
5192         talloc_destroy(mem_ctx);
5193
5194         if (!NT_STATUS_IS_OK(status)) {
5195                 errno = EACCES;
5196         }
5197
5198         return NT_STATUS_IS_OK(status);
5199 }
5200
5201 /****************************************************************************
5202  Check the time parameters allow a print operation.
5203 *****************************************************************************/
5204
5205 bool print_time_access_check(struct auth_serversupplied_info *server_info,
5206                              const char *servicename)
5207 {
5208         struct spoolss_PrinterInfo2 *pinfo2 = NULL;
5209         WERROR result;
5210         bool ok = False;
5211         time_t now = time(NULL);
5212         struct tm *t;
5213         uint32 mins;
5214
5215         result = winreg_get_printer(NULL, server_info,
5216                                     NULL, servicename, &pinfo2);
5217         if (!W_ERROR_IS_OK(result)) {
5218                 return False;
5219         }
5220
5221         if (pinfo2->starttime == 0 && pinfo2->untiltime == 0) {
5222                 ok = True;
5223         }
5224
5225         t = gmtime(&now);
5226         mins = (uint32)t->tm_hour*60 + (uint32)t->tm_min;
5227
5228         if (mins >= pinfo2->starttime && mins <= pinfo2->untiltime) {
5229                 ok = True;
5230         }
5231
5232         TALLOC_FREE(pinfo2);
5233
5234         if (!ok) {
5235                 errno = EACCES;
5236         }
5237
5238         return ok;
5239 }
5240
5241