Globally replace 'global_sam_sid' with get_global_sam_sid(), a self
[kai/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  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21
22 #include "includes.h"
23
24 extern DOM_SID global_sid_World;
25
26 static TDB_CONTEXT *tdb_forms; /* used for forms files */
27 static TDB_CONTEXT *tdb_drivers; /* used for driver files */
28 static TDB_CONTEXT *tdb_printers; /* used for printers files */
29
30 #define FORMS_PREFIX "FORMS/"
31 #define DRIVERS_PREFIX "DRIVERS/"
32 #define DRIVER_INIT_PREFIX "DRIVER_INIT/"
33 #define PRINTERS_PREFIX "PRINTERS/"
34 #define SECDESC_PREFIX "SECDESC/"
35 #define GLOBAL_C_SETPRINTER "GLOBALS/c_setprinter"
36  
37 #define NTDRIVERS_DATABASE_VERSION_1 1
38 #define NTDRIVERS_DATABASE_VERSION_2 2
39 #define NTDRIVERS_DATABASE_VERSION_3 3 /* little endian version of v2 */
40  
41 #define NTDRIVERS_DATABASE_VERSION NTDRIVERS_DATABASE_VERSION_3
42
43 /* Map generic permissions to printer object specific permissions */
44
45 GENERIC_MAPPING printer_generic_mapping = {
46         PRINTER_READ,
47         PRINTER_WRITE,
48         PRINTER_EXECUTE,
49         PRINTER_ALL_ACCESS
50 };
51
52 STANDARD_MAPPING printer_std_mapping = {
53         PRINTER_READ,
54         PRINTER_WRITE,
55         PRINTER_EXECUTE,
56         PRINTER_ALL_ACCESS
57 };
58
59 /* Map generic permissions to print server object specific permissions */
60
61 GENERIC_MAPPING printserver_generic_mapping = {
62         SERVER_READ,
63         SERVER_WRITE,
64         SERVER_EXECUTE,
65         SERVER_ALL_ACCESS
66 };
67
68 STANDARD_MAPPING printserver_std_mapping = {
69         SERVER_READ,
70         SERVER_WRITE,
71         SERVER_EXECUTE,
72         SERVER_ALL_ACCESS
73 };
74
75 /* We need one default form to support our default printer. Msoft adds the
76 forms it wants and in the ORDER it wants them (note: DEVMODE papersize is an
77 array index). Letter is always first, so (for the current code) additions
78 always put things in the correct order. */
79 static nt_forms_struct default_forms[] = {
80         {"Letter",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
81         {"Letter Small",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
82         {"Tabloid",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
83         {"Ledger",0x1,0x696b8,0x44368,0x0,0x0,0x696b8,0x44368},
84         {"Legal",0x1,0x34b5c,0x56d10,0x0,0x0,0x34b5c,0x56d10},
85         {"Statement",0x1,0x221b4,0x34b5c,0x0,0x0,0x221b4,0x34b5c},
86         {"Executive",0x1,0x2cf56,0x411cc,0x0,0x0,0x2cf56,0x411cc},
87         {"A3",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
88         {"A4",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
89         {"A4 Small",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
90         {"A5",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
91         {"B4 (JIS)",0x1,0x3ebe8,0x58de0,0x0,0x0,0x3ebe8,0x58de0},
92         {"B5 (JIS)",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
93         {"Folio",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
94         {"Quarto",0x1,0x347d8,0x43238,0x0,0x0,0x347d8,0x43238},
95         {"10x14",0x1,0x3e030,0x56d10,0x0,0x0,0x3e030,0x56d10},
96         {"11x17",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
97         {"Note",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
98         {"Envelope #9",0x1,0x18079,0x37091,0x0,0x0,0x18079,0x37091},
99         {"Envelope #10",0x1,0x19947,0x3ae94,0x0,0x0,0x19947,0x3ae94},
100         {"Envelope #11",0x1,0x1be7c,0x40565,0x0,0x0,0x1be7c,0x40565},
101         {"Envelope #12",0x1,0x1d74a,0x44368,0x0,0x0,0x1d74a,0x44368},
102         {"Envelope #14",0x1,0x1f018,0x47504,0x0,0x0,0x1f018,0x47504},
103         {"C size sheet",0x1,0x696b8,0x886d0,0x0,0x0,0x696b8,0x886d0},
104         {"D size sheet",0x1,0x886d0,0xd2d70,0x0,0x0,0x886d0,0xd2d70},
105         {"E size sheet",0x1,0xd2d70,0x110da0,0x0,0x0,0xd2d70,0x110da0},
106         {"Envelope DL",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
107         {"Envelope C5",0x1,0x278d0,0x37e88,0x0,0x0,0x278d0,0x37e88},
108         {"Envelope C3",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
109         {"Envelope C4",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
110         {"Envelope C6",0x1,0x1bd50,0x278d0,0x0,0x0,0x1bd50,0x278d0},
111         {"Envelope C65",0x1,0x1bd50,0x37e88,0x0,0x0,0x1bd50,0x37e88},
112         {"Envelope B4",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
113         {"Envelope B5",0x1,0x2af80,0x3d090,0x0,0x0,0x2af80,0x3d090},
114         {"Envelope B6",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
115         {"Envelope",0x1,0x1adb0,0x38270,0x0,0x0,0x1adb0,0x38270},
116         {"Envelope Monarch",0x1,0x18079,0x2e824,0x0,0x0,0x18079,0x2e824},
117         {"6 3/4 Envelope",0x1,0x167ab,0x284ec,0x0,0x0,0x167ab,0x284ec},
118         {"US Std Fanfold",0x1,0x5c3e1,0x44368,0x0,0x0,0x5c3e1,0x44368},
119         {"German Std Fanfold",0x1,0x34b5c,0x4a6a0,0x0,0x0,0x34b5c,0x4a6a0},
120         {"German Legal Fanfold",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
121         {"B4 (ISO)",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
122         {"Japanese Postcard",0x1,0x186a0,0x24220,0x0,0x0,0x186a0,0x24220},
123         {"9x11",0x1,0x37cf8,0x44368,0x0,0x0,0x37cf8,0x44368},
124         {"10x11",0x1,0x3e030,0x44368,0x0,0x0,0x3e030,0x44368},
125         {"15x11",0x1,0x5d048,0x44368,0x0,0x0,0x5d048,0x44368},
126         {"Envelope Invite",0x1,0x35b60,0x35b60,0x0,0x0,0x35b60,0x35b60},
127         {"Reserved48",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
128         {"Reserved49",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
129         {"Letter Extra",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
130         {"Legal Extra",0x1,0x3ae94,0x5d048,0x0,0x0,0x3ae94,0x5d048},
131         {"Tabloid Extra",0x1,0x4a6a0,0x6f9f0,0x0,0x0,0x4a6a0,0x6f9f0},
132         {"A4 Extra",0x1,0x397c2,0x4eb16,0x0,0x0,0x397c2,0x4eb16},
133         {"Letter Transverse",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
134         {"A4 Transverse",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
135         {"Letter Extra Transverse",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
136         {"Super A",0x1,0x376b8,0x56ea0,0x0,0x0,0x376b8,0x56ea0},
137         {"Super B",0x1,0x4a768,0x76e58,0x0,0x0,0x4a768,0x76e58},
138         {"Letter Plus",0x1,0x34b5c,0x4eb16,0x0,0x0,0x34b5c,0x4eb16},
139         {"A4 Plus",0x1,0x33450,0x50910,0x0,0x0,0x33450,0x50910},
140         {"A5 Transverse",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
141         {"B5 (JIS) Transverse",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
142         {"A3 Extra",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
143         {"A5 Extra",0x1,0x2a7b0,0x395f8,0x0,0x0,0x2a7b0,0x395f8},
144         {"B5 (ISO) Extra",0x1,0x31128,0x43620,0x0,0x0,0x31128,0x43620},
145         {"A2",0x1,0x668a0,0x91050,0x0,0x0,0x668a0,0x91050},
146         {"A3 Transverse",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
147         {"A3 Extra Transverse",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
148         {"Japanese Double Postcard",0x1,0x30d40,0x24220,0x0,0x0,0x30d40,0x24220},
149         {"A6",0x1,0x19a28,0x24220,0x0,0x0,0x19a28,0x24220},
150         {"Japanese Envelope Kaku #2",0x1,0x3a980,0x510e0,0x0,0x0,0x3a980,0x510e0},
151         {"Japanese Envelope Kaku #3",0x1,0x34bc0,0x43a08,0x0,0x0,0x34bc0,0x43a08},
152         {"Japanese Envelope Chou #3",0x1,0x1d4c0,0x395f8,0x0,0x0,0x1d4c0,0x395f8},
153         {"Japanese Envelope Chou #4",0x1,0x15f90,0x320c8,0x0,0x0,0x15f90,0x320c8},
154         {"Letter Rotated",0x1,0x44368,0x34b5c,0x0,0x0,0x44368,0x34b5c},
155         {"A3 Rotated",0x1,0x668a0,0x48828,0x0,0x0,0x668a0,0x48828},
156         {"A4 Rotated",0x1,0x48828,0x33450,0x0,0x0,0x48828,0x33450},
157         {"A5 Rotated",0x1,0x33450,0x24220,0x0,0x0,0x33450,0x24220},
158         {"B4 (JIS) Rotated",0x1,0x58de0,0x3ebe8,0x0,0x0,0x58de0,0x3ebe8},
159         {"B5 (JIS) Rotated",0x1,0x3ebe8,0x2c6f0,0x0,0x0,0x3ebe8,0x2c6f0},
160         {"Japanese Postcard Rotated",0x1,0x24220,0x186a0,0x0,0x0,0x24220,0x186a0},
161         {"Double Japan Postcard Rotated",0x1,0x24220,0x30d40,0x0,0x0,0x24220,0x30d40},
162         {"A6 Rotated",0x1,0x24220,0x19a28,0x0,0x0,0x24220,0x19a28},
163         {"Japan Envelope Kaku #2 Rotated",0x1,0x510e0,0x3a980,0x0,0x0,0x510e0,0x3a980},
164         {"Japan Envelope Kaku #3 Rotated",0x1,0x43a08,0x34bc0,0x0,0x0,0x43a08, 0x34bc0},
165         {"Japan Envelope Chou #3 Rotated",0x1,0x395f8,0x1d4c0,0x0,0x0,0x395f8,0x1d4c0},
166         {"Japan Envelope Chou #4 Rotated",0x1,0x320c8,0x15f90,0x0,0x0,0x320c8,0x15f90},
167         {"B6 (JIS)",0x1,0x1f400,0x2c6f0,0x0,0x0,0x1f400,0x2c6f0},
168         {"B6 (JIS) Rotated",0x1,0x2c6f0,0x1f400,0x0,0x0,0x2c6f0,0x1f400},
169         {"12x11",0x1,0x4a724,0x443e1,0x0,0x0,0x4a724,0x443e1},
170         {"Japan Envelope You #4",0x1,0x19a28,0x395f8,0x0,0x0,0x19a28,0x395f8},
171         {"Japan Envelope You #4 Rotated",0x1,0x395f8,0x19a28,0x0,0x0,0x395f8,0x19a28},
172         {"PRC 16K",0x1,0x2de60,0x3f7a0,0x0,0x0,0x2de60,0x3f7a0},
173         {"PRC 32K",0x1,0x1fbd0,0x2cec0,0x0,0x0,0x1fbd0,0x2cec0},
174         {"PRC 32K(Big)",0x1,0x222e0,0x318f8,0x0,0x0,0x222e0,0x318f8},
175         {"PRC Envelope #1",0x1,0x18e70,0x28488,0x0,0x0,0x18e70,0x28488},
176         {"PRC Envelope #2",0x1,0x18e70,0x2af80,0x0,0x0,0x18e70,0x2af80},
177         {"PRC Envelope #3",0x1,0x1e848,0x2af80,0x0,0x0,0x1e848,0x2af80},
178         {"PRC Envelope #4",0x1,0x1adb0,0x32c80,0x0,0x0,0x1adb0,0x32c80},
179         {"PRC Envelope #5",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
180         {"PRC Envelope #6",0x1,0x1d4c0,0x38270,0x0,0x0,0x1d4c0,0x38270},
181         {"PRC Envelope #7",0x1,0x27100,0x38270,0x0,0x0,0x27100,0x38270},
182         {"PRC Envelope #8",0x1,0x1d4c0,0x4b708,0x0,0x0,0x1d4c0,0x4b708},
183         {"PRC Envelope #9",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
184         {"PRC Envelope #10",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
185         {"PRC 16K Rotated",0x1,0x3f7a0,0x2de60,0x0,0x0,0x3f7a0,0x2de60},
186         {"PRC 32K Rotated",0x1,0x2cec0,0x1fbd0,0x0,0x0,0x2cec0,0x1fbd0},
187         {"PRC 32K(Big) Rotated",0x1,0x318f8,0x222e0,0x0,0x0,0x318f8,0x222e0},
188         {"PRC Envelope #1 Rotated",0x1,0x28488,0x18e70,0x0,0x0,0x28488,0x18e70},
189         {"PRC Envelope #2 Rotated",0x1,0x2af80,0x18e70,0x0,0x0,0x2af80,0x18e70},
190         {"PRC Envelope #3 Rotated",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
191         {"PRC Envelope #4 Rotated",0x1,0x32c80,0x1adb0,0x0,0x0,0x32c80,0x1adb0},
192         {"PRC Envelope #5 Rotated",0x1,0x35b60,0x1adb0,0x0,0x0,0x35b60,0x1adb0},
193         {"PRC Envelope #6 Rotated",0x1,0x38270,0x1d4c0,0x0,0x0,0x38270,0x1d4c0},
194         {"PRC Envelope #7 Rotated",0x1,0x38270,0x27100,0x0,0x0,0x38270,0x27100},
195         {"PRC Envelope #8 Rotated",0x1,0x4b708,0x1d4c0,0x0,0x0,0x4b708,0x1d4c0},
196         {"PRC Envelope #9 Rotated",0x1,0x4f1a0,0x37e88,0x0,0x0,0x4f1a0,0x37e88},
197         {"PRC Envelope #10 Rotated",0x1,0x6fd10,0x4f1a0,0x0,0x0,0x6fd10,0x4f1a0}
198 };
199
200 static BOOL upgrade_to_version_3(void)
201 {
202         TDB_DATA kbuf, newkey, dbuf;
203  
204         DEBUG(0,("upgrade_to_version_3: upgrading print tdb's to version 3\n"));
205  
206         for (kbuf = tdb_firstkey(tdb_drivers); kbuf.dptr;
207                         newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
208
209                 dbuf = tdb_fetch(tdb_drivers, kbuf);
210
211                 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
212                         DEBUG(0,("upgrade_to_version_3:moving form\n"));
213                         if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) {
214                                 DEBUG(0,("upgrade_to_version_3: failed to move form. Error (%s).\n", tdb_errorstr(tdb_forms)));
215                                 return False;
216                         }
217                         if (tdb_delete(tdb_drivers, kbuf) != 0) {
218                                 DEBUG(0,("upgrade_to_version_3: failed to delete form. Error (%s)\n", tdb_errorstr(tdb_drivers)));
219                                 return False;
220                         }
221                 }
222  
223                 if (strncmp(kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
224                         DEBUG(0,("upgrade_to_version_3:moving printer\n"));
225                         if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
226                                 DEBUG(0,("upgrade_to_version_3: failed to move printer. Error (%s)\n", tdb_errorstr(tdb_printers)));
227                                 return False;
228                         }
229                         if (tdb_delete(tdb_drivers, kbuf) != 0) {
230                                 DEBUG(0,("upgrade_to_version_3: failed to delete printer. Error (%s)\n", tdb_errorstr(tdb_drivers)));
231                                 return False;
232                         }
233                 }
234  
235                 if (strncmp(kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
236                         DEBUG(0,("upgrade_to_version_3:moving secdesc\n"));
237                         if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
238                                 DEBUG(0,("upgrade_to_version_3: failed to move secdesc. Error (%s)\n", tdb_errorstr(tdb_printers)));
239                                 return False;
240                         }
241                         if (tdb_delete(tdb_drivers, kbuf) != 0) {
242                                 DEBUG(0,("upgrade_to_version_3: failed to delete secdesc. Error (%s)\n", tdb_errorstr(tdb_drivers)));
243                                 return False;
244                         }
245                 }
246  
247                 SAFE_FREE(dbuf.dptr);
248         }
249
250         return True;
251 }
252
253 /****************************************************************************
254  Open the NT printing tdb.
255 ****************************************************************************/
256
257 BOOL nt_printing_init(void)
258 {
259         static pid_t local_pid;
260         char *vstring = "INFO/version";
261
262         if (tdb_drivers && tdb_printers && tdb_forms && local_pid == sys_getpid())
263                 return True;
264  
265         tdb_drivers = tdb_open_log(lock_path("ntdrivers.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
266         if (!tdb_drivers) {
267                 DEBUG(0,("nt_printing_init: Failed to open nt drivers database %s (%s)\n",
268                         lock_path("ntdrivers.tdb"), strerror(errno) ));
269                 return False;
270         }
271  
272         tdb_printers = tdb_open_log(lock_path("ntprinters.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
273         if (!tdb_printers) {
274                 DEBUG(0,("nt_printing_init: Failed to open nt printers database %s (%s)\n",
275                         lock_path("ntprinters.tdb"), strerror(errno) ));
276                 return False;
277         }
278  
279         tdb_forms = tdb_open_log(lock_path("ntforms.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
280         if (!tdb_forms) {
281                 DEBUG(0,("nt_printing_init: Failed to open nt forms database %s (%s)\n",
282                         lock_path("ntforms.tdb"), strerror(errno) ));
283                 return False;
284         }
285  
286         local_pid = sys_getpid();
287  
288         /* handle a Samba upgrade */
289         tdb_lock_bystring(tdb_drivers, vstring);
290         {
291                 int32 vers_id;
292
293                 /* Cope with byte-reversed older versions of the db. */
294                 vers_id = tdb_fetch_int32(tdb_drivers, vstring);
295                 if ((vers_id == NTDRIVERS_DATABASE_VERSION_2) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_2)) {
296                         /* Written on a bigendian machine with old fetch_int code. Save as le. */
297                         /* The only upgrade between V2 and V3 is to save the version in little-endian. */
298                         tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION);
299                         vers_id = NTDRIVERS_DATABASE_VERSION;
300                 }
301
302                 if (vers_id != NTDRIVERS_DATABASE_VERSION) {
303
304                         if ((vers_id == NTDRIVERS_DATABASE_VERSION_1) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_1)) { 
305                                 if (!upgrade_to_version_3())
306                                         return False;
307                         } else
308                                 tdb_traverse(tdb_drivers, tdb_traverse_delete_fn, NULL);
309                          
310                         tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION);
311                 }
312         }
313         tdb_unlock_bystring(tdb_drivers, vstring);
314
315         update_c_setprinter(True);
316
317         /*
318          * register callback to handle updating printers as new
319          * drivers are installed
320          */
321         message_register(MSG_PRINTER_DRVUPGRADE, do_drv_upgrade_printer);
322         return True;
323 }
324
325 /*******************************************************************
326  tdb traversal function for counting printers.
327 ********************************************************************/
328
329 static int traverse_counting_printers(TDB_CONTEXT *t, TDB_DATA key,
330                                       TDB_DATA data, void *context)
331 {
332         int *printer_count = (int*)context;
333  
334         if (memcmp(PRINTERS_PREFIX, key.dptr, sizeof(PRINTERS_PREFIX)-1) == 0) {
335                 (*printer_count)++;
336                 DEBUG(10,("traverse_counting_printers: printer = [%s]  printer_count = %d\n", key.dptr, *printer_count));
337         }
338  
339         return 0;
340 }
341  
342 /*******************************************************************
343  Update the spooler global c_setprinter. This variable is initialized
344  when the parent smbd starts with the number of existing printers. It
345  is monotonically increased by the current number of printers *after*
346  each add or delete printer RPC. Only Microsoft knows why... JRR020119
347 ********************************************************************/
348
349 uint32 update_c_setprinter(BOOL initialize)
350 {
351         int32 c_setprinter;
352         int32 printer_count = 0;
353  
354         tdb_lock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);
355  
356         /* Traverse the tdb, counting the printers */
357         tdb_traverse(tdb_printers, traverse_counting_printers, (void *)&printer_count);
358  
359         /* If initializing, set c_setprinter to current printers count
360          * otherwise, bump it by the current printer count
361          */
362         if (!initialize)
363                 c_setprinter = tdb_fetch_int32(tdb_printers, GLOBAL_C_SETPRINTER) + printer_count;
364         else
365                 c_setprinter = printer_count;
366  
367         DEBUG(10,("update_c_setprinter: c_setprinter = %u\n", (unsigned int)c_setprinter));
368         tdb_store_int32(tdb_printers, GLOBAL_C_SETPRINTER, c_setprinter);
369  
370         tdb_unlock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);
371  
372         return (uint32)c_setprinter;
373 }
374
375 /*******************************************************************
376  Get the spooler global c_setprinter, accounting for initialization.
377 ********************************************************************/
378
379 uint32 get_c_setprinter(void)
380 {
381         int32 c_setprinter = tdb_fetch_int32(tdb_printers, GLOBAL_C_SETPRINTER);
382  
383         if (c_setprinter == (int32)-1)
384                 c_setprinter = update_c_setprinter(True);
385  
386         DEBUG(10,("get_c_setprinter: c_setprinter = %d\n", c_setprinter));
387  
388         return (uint32)c_setprinter;
389 }
390
391 /****************************************************************************
392  Get builtin form struct list.
393 ****************************************************************************/
394
395 int get_builtin_ntforms(nt_forms_struct **list)
396 {
397         *list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));
398         return sizeof(default_forms) / sizeof(default_forms[0]);
399 }
400
401 /****************************************************************************
402  get a builtin form struct
403 ****************************************************************************/
404
405 BOOL get_a_builtin_ntform(UNISTR2 *uni_formname,nt_forms_struct *form)
406 {
407         int i,count;
408         fstring form_name;
409         unistr2_to_ascii(form_name, uni_formname, sizeof(form_name)-1);
410         DEBUGADD(6,("Looking for builtin form %s \n", form_name));
411         count = sizeof(default_forms) / sizeof(default_forms[0]);
412         for (i=0;i<count;i++) {
413                 if (strequal(form_name,default_forms[i].name)) {
414                         DEBUGADD(6,("Found builtin form %s \n", form_name));
415                         memcpy(form,&default_forms[i],sizeof(*form));
416                         break;
417                 }
418         }
419
420         return (i !=count);
421 }
422
423 /****************************************************************************
424 get a form struct list
425 ****************************************************************************/
426 int get_ntforms(nt_forms_struct **list)
427 {
428         TDB_DATA kbuf, newkey, dbuf;
429         nt_forms_struct *tl;
430         nt_forms_struct form;
431         int ret;
432         int i;
433         int n = 0;
434
435         for (kbuf = tdb_firstkey(tdb_forms);
436              kbuf.dptr;
437              newkey = tdb_nextkey(tdb_forms, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
438                 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0) continue;
439                 
440                 dbuf = tdb_fetch(tdb_forms, kbuf);
441                 if (!dbuf.dptr) continue;
442
443                 fstrcpy(form.name, kbuf.dptr+strlen(FORMS_PREFIX));
444                 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddd",
445                                  &i, &form.flag, &form.width, &form.length, &form.left,
446                                  &form.top, &form.right, &form.bottom);
447                 SAFE_FREE(dbuf.dptr);
448                 if (ret != dbuf.dsize) continue;
449
450                 tl = Realloc(*list, sizeof(nt_forms_struct)*(n+1));
451                 if (!tl) {
452                         DEBUG(0,("get_ntforms: Realloc fail.\n"));
453                         return 0;
454                 }
455         *list = tl;
456                 (*list)[n] = form;
457                 n++;
458         }
459         
460
461         return n;
462 }
463
464 /****************************************************************************
465 write a form struct list
466 ****************************************************************************/
467 int write_ntforms(nt_forms_struct **list, int number)
468 {
469         pstring buf, key;
470         int len;
471         TDB_DATA kbuf,dbuf;
472         int i;
473
474         for (i=0;i<number;i++) {
475                 /* save index, so list is rebuilt in correct order */
476                 len = tdb_pack(buf, sizeof(buf), "dddddddd",
477                                i, (*list)[i].flag, (*list)[i].width, (*list)[i].length,
478                                (*list)[i].left, (*list)[i].top, (*list)[i].right,
479                                (*list)[i].bottom);
480                 if (len > sizeof(buf)) break;
481                 slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[i].name);
482                 kbuf.dsize = strlen(key)+1;
483                 kbuf.dptr = key;
484                 dbuf.dsize = len;
485                 dbuf.dptr = buf;
486                 if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) break;
487        }
488
489        return i;
490 }
491
492 /****************************************************************************
493 add a form struct at the end of the list
494 ****************************************************************************/
495 BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
496 {
497         int n=0;
498         BOOL update;
499         fstring form_name;
500         nt_forms_struct *tl;
501
502         /*
503          * NT tries to add forms even when
504          * they are already in the base
505          * only update the values if already present
506          */
507
508         update=False;
509         
510         unistr2_to_ascii(form_name, &form->name, sizeof(form_name)-1);
511         for (n=0; n<*count; n++) {
512                 if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
513                         DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
514                         update=True;
515                         break;
516                 }
517         }
518
519         if (update==False) {
520                 if((tl=Realloc(*list, (n+1)*sizeof(nt_forms_struct))) == NULL) {
521                         DEBUG(0,("add_a_form: failed to enlarge forms list!\n"));
522                         return False;
523                 }
524                 *list = tl;
525                 unistr2_to_ascii((*list)[n].name, &form->name, sizeof((*list)[n].name)-1);
526                 (*count)++;
527         }
528         
529         (*list)[n].flag=form->flags;
530         (*list)[n].width=form->size_x;
531         (*list)[n].length=form->size_y;
532         (*list)[n].left=form->left;
533         (*list)[n].top=form->top;
534         (*list)[n].right=form->right;
535         (*list)[n].bottom=form->bottom;
536
537         return True;
538 }
539
540 /****************************************************************************
541  delete a named form struct
542 ****************************************************************************/
543 BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR *ret)
544 {
545         pstring key;
546         TDB_DATA kbuf;
547         int n=0;
548         fstring form_name;
549
550         *ret = WERR_OK;
551
552         unistr2_to_ascii(form_name, del_name, sizeof(form_name)-1);
553
554         for (n=0; n<*count; n++) {
555                 if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
556                         DEBUG(103, ("delete_a_form, [%s] in list\n", form_name));
557                         break;
558                 }
559         }
560
561         if (n == *count) {
562                 DEBUG(10,("delete_a_form, [%s] not found\n", form_name));
563                 *ret = WERR_INVALID_PARAM;
564                 return False;
565         }
566
567         slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[n].name);
568         kbuf.dsize = strlen(key)+1;
569         kbuf.dptr = key;
570         if (tdb_delete(tdb_forms, kbuf) != 0) {
571                 *ret = WERR_NOMEM;
572                 return False;
573         }
574
575         return True;
576 }
577
578 /****************************************************************************
579 update a form struct
580 ****************************************************************************/
581 void update_a_form(nt_forms_struct **list, const FORM *form, int count)
582 {
583         int n=0;
584         fstring form_name;
585         unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
586
587         DEBUG(106, ("[%s]\n", form_name));
588         for (n=0; n<count; n++)
589         {
590                 DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
591                 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
592                         break;
593         }
594
595         if (n==count) return;
596
597         (*list)[n].flag=form->flags;
598         (*list)[n].width=form->size_x;
599         (*list)[n].length=form->size_y;
600         (*list)[n].left=form->left;
601         (*list)[n].top=form->top;
602         (*list)[n].right=form->right;
603         (*list)[n].bottom=form->bottom;
604 }
605
606 /****************************************************************************
607 get the nt drivers list
608
609 traverse the database and look-up the matching names
610 ****************************************************************************/
611 int get_ntdrivers(fstring **list, char *architecture, uint32 version)
612 {
613         int total=0;
614         fstring short_archi;
615         fstring *fl;
616         pstring key;
617         TDB_DATA kbuf, newkey;
618
619         get_short_archi(short_archi, architecture);
620         slprintf(key, sizeof(key)-1, "%s%s/%d/", DRIVERS_PREFIX, short_archi, version);
621
622         for (kbuf = tdb_firstkey(tdb_drivers);
623              kbuf.dptr;
624              newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
625                 if (strncmp(kbuf.dptr, key, strlen(key)) != 0) continue;
626                 
627                 if((fl = Realloc(*list, sizeof(fstring)*(total+1))) == NULL) {
628                         DEBUG(0,("get_ntdrivers: failed to enlarge list!\n"));
629                         return -1;
630                 }
631                 else *list = fl;
632
633                 fstrcpy((*list)[total], kbuf.dptr+strlen(key));
634                 total++;
635         }
636
637         return(total);
638 }
639
640 /****************************************************************************
641 function to do the mapping between the long architecture name and
642 the short one.
643 ****************************************************************************/
644 BOOL get_short_archi(char *short_archi, char *long_archi)
645 {
646         struct table {
647                 char *long_archi;
648                 char *short_archi;
649         };
650         
651         struct table archi_table[]=
652         {
653                 {"Windows 4.0",          "WIN40"    },
654                 {"Windows NT x86",       "W32X86"   },
655                 {"Windows NT R4000",     "W32MIPS"  },
656                 {"Windows NT Alpha_AXP", "W32ALPHA" },
657                 {"Windows NT PowerPC",   "W32PPC"   },
658                 {NULL,                   ""         }
659         };
660         
661         int i=-1;
662
663         DEBUG(107,("Getting architecture dependant directory\n"));
664         do {
665                 i++;
666         } while ( (archi_table[i].long_archi!=NULL ) &&
667                   StrCaseCmp(long_archi, archi_table[i].long_archi) );
668
669         if (archi_table[i].long_archi==NULL) {
670                 DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
671                 return False;
672         }
673
674         StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
675
676         DEBUGADD(108,("index: [%d]\n", i));
677         DEBUGADD(108,("long architecture: [%s]\n", long_archi));
678         DEBUGADD(108,("short architecture: [%s]\n", short_archi));
679         
680         return True;
681 }
682
683 /****************************************************************************
684  Version information in Microsoft files is held in a VS_VERSION_INFO structure.
685  There are two case to be covered here: PE (Portable Executable) and NE (New
686  Executable) files. Both files support the same INFO structure, but PE files
687  store the signature in unicode, and NE files store it as !unicode.
688  returns -1 on error, 1 on version info found, and 0 on no version info found.
689 ****************************************************************************/
690
691 static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 *minor)
692 {
693         int     i;
694         char    *buf;
695         ssize_t byte_count;
696
697         if ((buf=malloc(PE_HEADER_SIZE)) == NULL) {
698                 DEBUG(0,("get_file_version: PE file [%s] PE Header malloc failed bytes = %d\n",
699                                 fname, PE_HEADER_SIZE));
700                 goto error_exit;
701         }
702
703         /* Note: DOS_HEADER_SIZE < malloc'ed PE_HEADER_SIZE */
704         if ((byte_count = vfs_read_data(fsp, buf, DOS_HEADER_SIZE)) < DOS_HEADER_SIZE) {
705                 DEBUG(3,("get_file_version: File [%s] DOS header too short, bytes read = %d\n",
706                                 fname, byte_count));
707                 goto no_version_info;
708         }
709
710         /* Is this really a DOS header? */
711         if (SVAL(buf,DOS_HEADER_MAGIC_OFFSET) != DOS_HEADER_MAGIC) {
712                 DEBUG(6,("get_file_version: File [%s] bad DOS magic = 0x%x\n",
713                                 fname, SVAL(buf,DOS_HEADER_MAGIC_OFFSET)));
714                 goto no_version_info;
715         }
716
717         /* Skip OEM header (if any) and the DOS stub to start of Windows header */
718         if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
719                 DEBUG(3,("get_file_version: File [%s] too short, errno = %d\n",
720                                 fname, errno));
721                 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
722                 goto no_version_info;
723         }
724
725         if ((byte_count = vfs_read_data(fsp, buf, PE_HEADER_SIZE)) < PE_HEADER_SIZE) {
726                 DEBUG(3,("get_file_version: File [%s] Windows header too short, bytes read = %d\n",
727                                 fname, byte_count));
728                 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
729                 goto no_version_info;
730         }
731
732         /* The header may be a PE (Portable Executable) or an NE (New Executable) */
733         if (IVAL(buf,PE_HEADER_SIGNATURE_OFFSET) == PE_HEADER_SIGNATURE) {
734                 int num_sections;
735                 int section_table_bytes;
736                 
737                 if (SVAL(buf,PE_HEADER_MACHINE_OFFSET) != PE_HEADER_MACHINE_I386) {
738                         DEBUG(3,("get_file_version: PE file [%s] wrong machine = 0x%x\n",
739                                         fname, SVAL(buf,PE_HEADER_MACHINE_OFFSET)));
740                         /* At this point, we assume the file is in error. It still could be somthing
741                          * else besides a PE file, but it unlikely at this point.
742                          */
743                         goto error_exit;
744                 }
745
746                 /* get the section table */
747                 num_sections        = SVAL(buf,PE_HEADER_NUMBER_OF_SECTIONS);
748                 section_table_bytes = num_sections * PE_HEADER_SECT_HEADER_SIZE;
749                 SAFE_FREE(buf);
750                 if ((buf=malloc(section_table_bytes)) == NULL) {
751                         DEBUG(0,("get_file_version: PE file [%s] section table malloc failed bytes = %d\n",
752                                         fname, section_table_bytes));
753                         goto error_exit;
754                 }
755
756                 if ((byte_count = vfs_read_data(fsp, buf, section_table_bytes)) < section_table_bytes) {
757                         DEBUG(3,("get_file_version: PE file [%s] Section header too short, bytes read = %d\n",
758                                         fname, byte_count));
759                         goto error_exit;
760                 }
761
762                 /* Iterate the section table looking for the resource section ".rsrc" */
763                 for (i = 0; i < num_sections; i++) {
764                         int sec_offset = i * PE_HEADER_SECT_HEADER_SIZE;
765
766                         if (strcmp(".rsrc", &buf[sec_offset+PE_HEADER_SECT_NAME_OFFSET]) == 0) {
767                                 int section_pos   = IVAL(buf,sec_offset+PE_HEADER_SECT_PTR_DATA_OFFSET);
768                                 int section_bytes = IVAL(buf,sec_offset+PE_HEADER_SECT_SIZE_DATA_OFFSET);
769
770                                 SAFE_FREE(buf);
771                                 if ((buf=malloc(section_bytes)) == NULL) {
772                                         DEBUG(0,("get_file_version: PE file [%s] version malloc failed bytes = %d\n",
773                                                         fname, section_bytes));
774                                         goto error_exit;
775                                 }
776
777                                 /* Seek to the start of the .rsrc section info */
778                                 if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, section_pos, SEEK_SET) == (SMB_OFF_T)-1) {
779                                         DEBUG(3,("get_file_version: PE file [%s] too short for section info, errno = %d\n",
780                                                         fname, errno));
781                                         goto error_exit;
782                                 }
783
784                                 if ((byte_count = vfs_read_data(fsp, buf, section_bytes)) < section_bytes) {
785                                         DEBUG(3,("get_file_version: PE file [%s] .rsrc section too short, bytes read = %d\n",
786                                                         fname, byte_count));
787                                         goto error_exit;
788                                 }
789
790                                 for (i=0; i<section_bytes-VS_VERSION_INFO_UNICODE_SIZE; i++) {
791                                         /* Scan for 1st 3 unicoded bytes followed by word aligned magic value */
792                                         if (buf[i] == 'V' && buf[i+1] == '\0' && buf[i+2] == 'S') {
793                                                 /* Align to next long address */
794                                                 int pos = (i + sizeof(VS_SIGNATURE)*2 + 3) & 0xfffffffc;
795
796                                                 if (IVAL(buf,pos) == VS_MAGIC_VALUE) {
797                                                         *major = IVAL(buf,pos+VS_MAJOR_OFFSET);
798                                                         *minor = IVAL(buf,pos+VS_MINOR_OFFSET);
799                                                         
800                                                         DEBUG(6,("get_file_version: PE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
801                                                                           fname, *major, *minor,
802                                                                           (*major>>16)&0xffff, *major&0xffff,
803                                                                           (*minor>>16)&0xffff, *minor&0xffff));
804                                                         SAFE_FREE(buf);
805                                                         return 1;
806                                                 }
807                                         }
808                                 }
809                         }
810                 }
811
812                 /* Version info not found, fall back to origin date/time */
813                 DEBUG(10,("get_file_version: PE file [%s] has no version info\n", fname));
814                 SAFE_FREE(buf);
815                 return 0;
816
817         } else if (SVAL(buf,NE_HEADER_SIGNATURE_OFFSET) == NE_HEADER_SIGNATURE) {
818                 if (CVAL(buf,NE_HEADER_TARGET_OS_OFFSET) != NE_HEADER_TARGOS_WIN ) {
819                         DEBUG(3,("get_file_version: NE file [%s] wrong target OS = 0x%x\n",
820                                         fname, CVAL(buf,NE_HEADER_TARGET_OS_OFFSET)));
821                         /* At this point, we assume the file is in error. It still could be somthing
822                          * else besides a NE file, but it unlikely at this point. */
823                         goto error_exit;
824                 }
825
826                 /* Allocate a bit more space to speed up things */
827                 SAFE_FREE(buf);
828                 if ((buf=malloc(VS_NE_BUF_SIZE)) == NULL) {
829                         DEBUG(0,("get_file_version: NE file [%s] malloc failed bytes  = %d\n",
830                                         fname, PE_HEADER_SIZE));
831                         goto error_exit;
832                 }
833
834                 /* This is a HACK! I got tired of trying to sort through the messy
835                  * 'NE' file format. If anyone wants to clean this up please have at
836                  * it, but this works. 'NE' files will eventually fade away. JRR */
837                 while((byte_count = vfs_read_data(fsp, buf, VS_NE_BUF_SIZE)) > 0) {
838                         /* Cover case that should not occur in a well formed 'NE' .dll file */
839                         if (byte_count-VS_VERSION_INFO_SIZE <= 0) break;
840
841                         for(i=0; i<byte_count; i++) {
842                                 /* Fast skip past data that can't possibly match */
843                                 if (buf[i] != 'V') continue;
844
845                                 /* Potential match data crosses buf boundry, move it to beginning
846                                  * of buf, and fill the buf with as much as it will hold. */
847                                 if (i>byte_count-VS_VERSION_INFO_SIZE) {
848                                         int bc;
849
850                                         memcpy(buf, &buf[i], byte_count-i);
851                                         if ((bc = vfs_read_data(fsp, &buf[byte_count-i], VS_NE_BUF_SIZE-
852                                                                    (byte_count-i))) < 0) {
853
854                                                 DEBUG(0,("get_file_version: NE file [%s] Read error, errno=%d\n",
855                                                                  fname, errno));
856                                                 goto error_exit;
857                                         }
858
859                                         byte_count = bc + (byte_count - i);
860                                         if (byte_count<VS_VERSION_INFO_SIZE) break;
861
862                                         i = 0;
863                                 }
864
865                                 /* Check that the full signature string and the magic number that
866                                  * follows exist (not a perfect solution, but the chances that this
867                                  * occurs in code is, well, remote. Yes I know I'm comparing the 'V'
868                                  * twice, as it is simpler to read the code. */
869                                 if (strcmp(&buf[i], VS_SIGNATURE) == 0) {
870                                         /* Compute skip alignment to next long address */
871                                         int skip = -(fsp->conn->vfs_ops.lseek(fsp, fsp->fd, 0, SEEK_CUR) - (byte_count - i) +
872                                                                  sizeof(VS_SIGNATURE)) & 3;
873                                         if (IVAL(buf,i+sizeof(VS_SIGNATURE)+skip) != 0xfeef04bd) continue;
874
875                                         *major = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MAJOR_OFFSET);
876                                         *minor = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MINOR_OFFSET);
877                                         DEBUG(6,("get_file_version: NE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
878                                                           fname, *major, *minor,
879                                                           (*major>>16)&0xffff, *major&0xffff,
880                                                           (*minor>>16)&0xffff, *minor&0xffff));
881                                         SAFE_FREE(buf);
882                                         return 1;
883                                 }
884                         }
885                 }
886
887                 /* Version info not found, fall back to origin date/time */
888                 DEBUG(0,("get_file_version: NE file [%s] Version info not found\n", fname));
889                 SAFE_FREE(buf);
890                 return 0;
891
892         } else
893                 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
894                 DEBUG(3,("get_file_version: File [%s] unknown file format, signature = 0x%x\n",
895                                 fname, IVAL(buf,PE_HEADER_SIGNATURE_OFFSET)));
896
897         no_version_info:
898                 SAFE_FREE(buf);
899                 return 0;
900
901         error_exit:
902                 SAFE_FREE(buf);
903                 return -1;
904 }
905
906 /****************************************************************************
907 Drivers for Microsoft systems contain multiple files. Often, multiple drivers
908 share one or more files. During the MS installation process files are checked
909 to insure that only a newer version of a shared file is installed over an
910 older version. There are several possibilities for this comparison. If there
911 is no previous version, the new one is newer (obviously). If either file is
912 missing the version info structure, compare the creation date (on Unix use
913 the modification date). Otherwise chose the numerically larger version number.
914 ****************************************************************************/
915 static int file_version_is_newer(connection_struct *conn, fstring new_file,
916                                                                 fstring old_file)
917 {
918         BOOL   use_version = True;
919         pstring filepath;
920
921         uint32 new_major;
922         uint32 new_minor;
923         time_t new_create_time;
924
925         uint32 old_major;
926         uint32 old_minor;
927         time_t old_create_time;
928
929         int access_mode;
930         int action;
931         files_struct    *fsp = NULL;
932         SMB_STRUCT_STAT st;
933         SMB_STRUCT_STAT stat_buf;
934         BOOL bad_path;
935
936         ZERO_STRUCT(st);
937         ZERO_STRUCT(stat_buf);
938         new_create_time = (time_t)0;
939         old_create_time = (time_t)0;
940
941         /* Get file version info (if available) for previous file (if it exists) */
942         pstrcpy(filepath, old_file);
943
944         unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
945
946         fsp = open_file_shared(conn, filepath, &stat_buf,
947                                                    SET_OPEN_MODE(DOS_OPEN_RDONLY),
948                                                    (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
949                                                    0, 0, &access_mode, &action);
950         if (!fsp) {
951                 /* Old file not found, so by definition new file is in fact newer */
952                 DEBUG(10,("file_version_is_newer: Can't open old file [%s], errno = %d\n",
953                                 filepath, errno));
954                 return True;
955
956         } else {
957                 int ret = get_file_version(fsp, old_file, &old_major, &old_minor);
958                 if (ret == -1) goto error_exit;
959
960                 if (!ret) {
961                         DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
962                                          old_file));
963                         use_version = False;
964                         if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit;
965                         old_create_time = st.st_mtime;
966                         DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", old_create_time));
967                 }
968         }
969         close_file(fsp, True);
970
971         /* Get file version info (if available) for new file */
972         pstrcpy(filepath, new_file);
973         unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
974
975         fsp = open_file_shared(conn, filepath, &stat_buf,
976                                                    SET_OPEN_MODE(DOS_OPEN_RDONLY),
977                                                    (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
978                                                    0, 0, &access_mode, &action);
979         if (!fsp) {
980                 /* New file not found, this shouldn't occur if the caller did its job */
981                 DEBUG(3,("file_version_is_newer: Can't open new file [%s], errno = %d\n",
982                                 filepath, errno));
983                 goto error_exit;
984
985         } else {
986                 int ret = get_file_version(fsp, new_file, &new_major, &new_minor);
987                 if (ret == -1) goto error_exit;
988
989                 if (!ret) {
990                         DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
991                                          new_file));
992                         use_version = False;
993                         if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit;
994                         new_create_time = st.st_mtime;
995                         DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", new_create_time));
996                 }
997         }
998         close_file(fsp, True);
999
1000         if (use_version) {
1001                 /* Compare versions and choose the larger version number */
1002                 if (new_major > old_major ||
1003                         (new_major == old_major && new_minor > old_minor)) {
1004                         
1005                         DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
1006                         return True;
1007                 }
1008                 else {
1009                         DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
1010                         return False;
1011                 }
1012
1013         } else {
1014                 /* Compare modification time/dates and choose the newest time/date */
1015                 if (new_create_time > old_create_time) {
1016                         DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
1017                         return True;
1018                 }
1019                 else {
1020                         DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
1021                         return False;
1022                 }
1023         }
1024
1025         error_exit:
1026                 if(fsp)
1027                         close_file(fsp, True);
1028                 return -1;
1029 }
1030
1031 /****************************************************************************
1032 Determine the correct cVersion associated with an architecture and driver
1033 ****************************************************************************/
1034 static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in,
1035                                    struct current_user *user, WERROR *perr)
1036 {
1037         int               cversion;
1038         int               access_mode;
1039         int               action;
1040         NTSTATUS          nt_status;
1041         pstring           driverpath;
1042         DATA_BLOB         null_pw;
1043         files_struct      *fsp = NULL;
1044         BOOL              bad_path;
1045         SMB_STRUCT_STAT   st;
1046         connection_struct *conn;
1047
1048         ZERO_STRUCT(st);
1049
1050         *perr = WERR_INVALID_PARAM;
1051
1052         /* If architecture is Windows 95/98/ME, the version is always 0. */
1053         if (strcmp(architecture, "WIN40") == 0) {
1054                 DEBUG(10,("get_correct_cversion: Driver is Win9x, cversion = 0\n"));
1055                 *perr = WERR_OK;
1056                 return 0;
1057         }
1058
1059         /*
1060          * Connect to the print$ share under the same account as the user connected
1061          * to the rpc pipe. Note we must still be root to do this.
1062          */
1063
1064         /* Null password is ok - we are already an authenticated user... */
1065         null_pw = data_blob(NULL, 0);
1066         become_root();
1067         conn = make_connection("print$", null_pw, "A:", user->vuid, &nt_status);
1068         unbecome_root();
1069
1070         if (conn == NULL) {
1071                 DEBUG(0,("get_correct_cversion: Unable to connect\n"));
1072                 *perr = ntstatus_to_werror(nt_status);
1073                 return -1;
1074         }
1075
1076         /* We are temporarily becoming the connection user. */
1077         if (!become_user(conn, conn->vuid)) {
1078                 DEBUG(0,("get_correct_cversion: Can't become user!\n"));
1079                 *perr = WERR_ACCESS_DENIED;
1080                 return -1;
1081         }
1082
1083         /* Open the driver file (Portable Executable format) and determine the
1084          * deriver the cversion. */
1085         slprintf(driverpath, sizeof(driverpath)-1, "%s/%s", architecture, driverpath_in);
1086
1087         unix_convert(driverpath,conn,NULL,&bad_path,&st);
1088
1089         fsp = open_file_shared(conn, driverpath, &st,
1090                                                    SET_OPEN_MODE(DOS_OPEN_RDONLY),
1091                                                    (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
1092                                                    0, 0, &access_mode, &action);
1093         if (!fsp) {
1094                 DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
1095                                 driverpath, errno));
1096                 *perr = WERR_ACCESS_DENIED;
1097                 goto error_exit;
1098         }
1099         else {
1100                 uint32 major;
1101                 uint32 minor;
1102                 int    ret = get_file_version(fsp, driverpath, &major, &minor);
1103                 if (ret == -1) goto error_exit;
1104
1105                 if (!ret) {
1106                         DEBUG(6,("get_correct_cversion: Version info not found [%s]\n", driverpath));
1107                         goto error_exit;
1108                 }
1109
1110                 /*
1111                  * This is a Microsoft'ism. See references in MSDN to VER_FILEVERSION
1112                  * for more details. Version in this case is not just the version of the 
1113                  * file, but the version in the sense of kernal mode (2) vs. user mode
1114                  * (3) drivers. Other bits of the version fields are the version info. 
1115                  * JRR 010716
1116                 */
1117                 cversion = major & 0x0000ffff;
1118                 switch (cversion) {
1119                         case 2: /* WinNT drivers */
1120                         case 3: /* Win2K drivers */
1121                                 break;
1122                         
1123                         default:
1124                                 DEBUG(6,("get_correct_cversion: cversion invalid [%s]  cversion = %d\n", 
1125                                         driverpath, cversion));
1126                                 goto error_exit;
1127                 }
1128
1129                 DEBUG(10,("get_correct_cversion: Version info found [%s]  major = 0x%x  minor = 0x%x\n",
1130                                   driverpath, major, minor));
1131         }
1132
1133     DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
1134                         driverpath, cversion));
1135
1136         close_file(fsp, True);
1137         close_cnum(conn, user->vuid);
1138         unbecome_user();
1139         *perr = WERR_OK;
1140         return cversion;
1141
1142
1143   error_exit:
1144
1145         if(fsp)
1146                 close_file(fsp, True);
1147
1148         close_cnum(conn, user->vuid);
1149         unbecome_user();
1150         return -1;
1151 }
1152
1153 /****************************************************************************
1154 ****************************************************************************/
1155 static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver,
1156                                                                                          struct current_user *user)
1157 {
1158         fstring architecture;
1159         fstring new_name;
1160         char *p;
1161         int i;
1162         WERROR err;
1163
1164         /* clean up the driver name.
1165          * we can get .\driver.dll
1166          * or worse c:\windows\system\driver.dll !
1167          */
1168         /* using an intermediate string to not have overlaping memcpy()'s */
1169         if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
1170                 fstrcpy(new_name, p+1);
1171                 fstrcpy(driver->driverpath, new_name);
1172         }
1173
1174         if ((p = strrchr(driver->datafile,'\\')) != NULL) {
1175                 fstrcpy(new_name, p+1);
1176                 fstrcpy(driver->datafile, new_name);
1177         }
1178
1179         if ((p = strrchr(driver->configfile,'\\')) != NULL) {
1180                 fstrcpy(new_name, p+1);
1181                 fstrcpy(driver->configfile, new_name);
1182         }
1183
1184         if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
1185                 fstrcpy(new_name, p+1);
1186                 fstrcpy(driver->helpfile, new_name);
1187         }
1188
1189         if (driver->dependentfiles) {
1190                 for (i=0; *driver->dependentfiles[i]; i++) {
1191                         if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
1192                                 fstrcpy(new_name, p+1);
1193                                 fstrcpy(driver->dependentfiles[i], new_name);
1194                         }
1195                 }
1196         }
1197
1198         get_short_archi(architecture, driver->environment);
1199         
1200         /* jfm:7/16/2000 the client always sends the cversion=0.
1201          * The server should check which version the driver is by reading
1202          * the PE header of driver->driverpath.
1203          *
1204          * For Windows 95/98 the version is 0 (so the value sent is correct)
1205          * For Windows NT (the architecture doesn't matter)
1206          *      NT 3.1: cversion=0
1207          *      NT 3.5/3.51: cversion=1
1208          *      NT 4: cversion=2
1209          *      NT2K: cversion=3
1210          */
1211         if ((driver->cversion = get_correct_cversion( architecture,
1212                                                                         driver->driverpath, user, &err)) == -1)
1213                 return err;
1214
1215         return WERR_OK;
1216 }
1217         
1218 /****************************************************************************
1219 ****************************************************************************/
1220 static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver,
1221                                                                                          struct current_user *user)
1222 {
1223         fstring architecture;
1224         fstring new_name;
1225         char *p;
1226         int i;
1227         WERROR err;
1228
1229         /* clean up the driver name.
1230          * we can get .\driver.dll
1231          * or worse c:\windows\system\driver.dll !
1232          */
1233         /* using an intermediate string to not have overlaping memcpy()'s */
1234         if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
1235                 fstrcpy(new_name, p+1);
1236                 fstrcpy(driver->driverpath, new_name);
1237         }
1238
1239         if ((p = strrchr(driver->datafile,'\\')) != NULL) {
1240                 fstrcpy(new_name, p+1);
1241                 fstrcpy(driver->datafile, new_name);
1242         }
1243
1244         if ((p = strrchr(driver->configfile,'\\')) != NULL) {
1245                 fstrcpy(new_name, p+1);
1246                 fstrcpy(driver->configfile, new_name);
1247         }
1248
1249         if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
1250                 fstrcpy(new_name, p+1);
1251                 fstrcpy(driver->helpfile, new_name);
1252         }
1253
1254         if (driver->dependentfiles) {
1255                 for (i=0; *driver->dependentfiles[i]; i++) {
1256                         if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
1257                                 fstrcpy(new_name, p+1);
1258                                 fstrcpy(driver->dependentfiles[i], new_name);
1259                         }
1260                 }
1261         }
1262
1263         get_short_archi(architecture, driver->environment);
1264
1265         /* jfm:7/16/2000 the client always sends the cversion=0.
1266          * The server should check which version the driver is by reading
1267          * the PE header of driver->driverpath.
1268          *
1269          * For Windows 95/98 the version is 0 (so the value sent is correct)
1270          * For Windows NT (the architecture doesn't matter)
1271          *      NT 3.1: cversion=0
1272          *      NT 3.5/3.51: cversion=1
1273          *      NT 4: cversion=2
1274          *      NT2K: cversion=3
1275          */
1276         if ((driver->version = get_correct_cversion(architecture,
1277                                                                         driver->driverpath, user, &err)) == -1)
1278                 return err;
1279
1280         return WERR_OK;
1281 }
1282
1283 /****************************************************************************
1284 ****************************************************************************/
1285 WERROR clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
1286                                                           uint32 level, struct current_user *user)
1287 {
1288         switch (level) {
1289                 case 3:
1290                 {
1291                         NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
1292                         driver=driver_abstract.info_3;
1293                         return clean_up_driver_struct_level_3(driver, user);
1294                 }
1295                 case 6:
1296                 {
1297                         NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver;
1298                         driver=driver_abstract.info_6;
1299                         return clean_up_driver_struct_level_6(driver, user);
1300                 }
1301                 default:
1302                         return WERR_INVALID_PARAM;
1303         }
1304 }
1305
1306 /****************************************************************************
1307  This function sucks and should be replaced. JRA.
1308 ****************************************************************************/
1309
1310 static void convert_level_6_to_level3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dst, NT_PRINTER_DRIVER_INFO_LEVEL_6 *src)
1311 {
1312     dst->cversion  = src->version;
1313
1314     fstrcpy( dst->name, src->name);
1315     fstrcpy( dst->environment, src->environment);
1316     fstrcpy( dst->driverpath, src->driverpath);
1317     fstrcpy( dst->datafile, src->datafile);
1318     fstrcpy( dst->configfile, src->configfile);
1319     fstrcpy( dst->helpfile, src->helpfile);
1320     fstrcpy( dst->monitorname, src->monitorname);
1321     fstrcpy( dst->defaultdatatype, src->defaultdatatype);
1322     dst->dependentfiles = src->dependentfiles;
1323 }
1324
1325 #if 0 /* Debugging function */
1326
1327 static char* ffmt(unsigned char *c){
1328         int i;
1329         static char ffmt_str[17];
1330
1331         for (i=0; i<16; i++) {
1332                 if ((c[i] < ' ') || (c[i] > '~'))
1333                         ffmt_str[i]='.';
1334                 else
1335                         ffmt_str[i]=c[i];
1336         }
1337     ffmt_str[16]='\0';
1338         return ffmt_str;
1339 }
1340
1341 #endif
1342
1343 /****************************************************************************
1344 ****************************************************************************/
1345 BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level, 
1346                                   struct current_user *user, WERROR *perr)
1347 {
1348         NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
1349         NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver;
1350         fstring architecture;
1351         pstring new_dir;
1352         pstring old_name;
1353         pstring new_name;
1354         DATA_BLOB null_pw;
1355         connection_struct *conn;
1356         NTSTATUS nt_status;
1357         pstring inbuf;
1358         pstring outbuf;
1359         int ver = 0;
1360         int i;
1361
1362         memset(inbuf, '\0', sizeof(inbuf));
1363         memset(outbuf, '\0', sizeof(outbuf));
1364         *perr = WERR_OK;
1365
1366         if (level==3)
1367                 driver=driver_abstract.info_3;
1368         else if (level==6) {
1369                 convert_level_6_to_level3(&converted_driver, driver_abstract.info_6);
1370                 driver = &converted_driver;
1371         } else {
1372                 DEBUG(0,("move_driver_to_download_area: Unknown info level (%u)\n", (unsigned int)level ));
1373                 return False;
1374         }
1375
1376         get_short_archi(architecture, driver->environment);
1377
1378         /*
1379          * Connect to the print$ share under the same account as the user connected to the rpc pipe.
1380          * Note we must be root to do this.
1381          */
1382
1383         become_root();
1384         null_pw = data_blob(NULL, 0);
1385         conn = make_connection("print$", null_pw, "A:", user->vuid, &nt_status);
1386         unbecome_root();
1387
1388         if (conn == NULL) {
1389                 DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
1390                 *perr = ntstatus_to_werror(nt_status);
1391                 return False;
1392         }
1393
1394         /*
1395          * Save who we are - we are temporarily becoming the connection user.
1396          */
1397
1398         if (!become_user(conn, conn->vuid)) {
1399                 DEBUG(0,("move_driver_to_download_area: Can't become user!\n"));
1400                 return False;
1401         }
1402
1403         /*
1404          * make the directories version and version\driver_name
1405          * under the architecture directory.
1406          */
1407         DEBUG(5,("Creating first directory\n"));
1408         slprintf(new_dir, sizeof(new_dir)-1, "%s/%d", architecture, driver->cversion);
1409         mkdir_internal(conn, new_dir);
1410
1411         /* For each driver file, archi\filexxx.yyy, if there is a duplicate file
1412          * listed for this driver which has already been moved, skip it (note:
1413          * drivers may list the same file name several times. Then check if the
1414          * file already exists in archi\cversion\, if so, check that the version
1415          * info (or time stamps if version info is unavailable) is newer (or the
1416          * date is later). If it is, move it to archi\cversion\filexxx.yyy.
1417          * Otherwise, delete the file.
1418          *
1419          * If a file is not moved to archi\cversion\ because of an error, all the
1420          * rest of the 'unmoved' driver files are removed from archi\. If one or
1421          * more of the driver's files was already moved to archi\cversion\, it
1422          * potentially leaves the driver in a partially updated state. Version
1423          * trauma will most likely occur if an client attempts to use any printer
1424          * bound to the driver. Perhaps a rewrite to make sure the moves can be
1425          * done is appropriate... later JRR
1426          */
1427
1428         DEBUG(5,("Moving files now !\n"));
1429
1430         if (driver->driverpath && strlen(driver->driverpath)) {
1431                 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->driverpath);      
1432                 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->driverpath);   
1433                 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1434                         NTSTATUS status;
1435                         status = rename_internals(conn, new_name, old_name, True);
1436                         if (!NT_STATUS_IS_OK(status)) {
1437                                 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1438                                                 new_name, old_name));
1439                                 *perr = ntstatus_to_werror(status);
1440                                 unlink_internals(conn, 0, new_name);
1441                                 ver = -1;
1442                         }
1443                 }
1444                 else
1445                         unlink_internals(conn, 0, new_name);
1446         }
1447
1448         if (driver->datafile && strlen(driver->datafile)) {
1449                 if (!strequal(driver->datafile, driver->driverpath)) {
1450                         slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->datafile);        
1451                         slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->datafile);     
1452                         if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1453                                 NTSTATUS status;
1454                                 status = rename_internals(conn, new_name, old_name, True);
1455                                 if (!NT_STATUS_IS_OK(status)) {
1456                                         DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1457                                                         new_name, old_name));
1458                                         *perr = ntstatus_to_werror(status);
1459                                         unlink_internals(conn, 0, new_name);
1460                                         ver = -1;
1461                                 }
1462                         }
1463                         else
1464                                 unlink_internals(conn, 0, new_name);
1465                 }
1466         }
1467
1468         if (driver->configfile && strlen(driver->configfile)) {
1469                 if (!strequal(driver->configfile, driver->driverpath) &&
1470                         !strequal(driver->configfile, driver->datafile)) {
1471                         slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->configfile);      
1472                         slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->configfile);   
1473                         if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1474                                 NTSTATUS status;
1475                                 status = rename_internals(conn, new_name, old_name, True);
1476                                 if (!NT_STATUS_IS_OK(status)) {
1477                                         DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1478                                                         new_name, old_name));
1479                                         *perr = ntstatus_to_werror(status);
1480                                         unlink_internals(conn, 0, new_name);
1481                                         ver = -1;
1482                                 }
1483                         }
1484                         else
1485                                 unlink_internals(conn, 0, new_name);
1486                 }
1487         }
1488
1489         if (driver->helpfile && strlen(driver->helpfile)) {
1490                 if (!strequal(driver->helpfile, driver->driverpath) &&
1491                         !strequal(driver->helpfile, driver->datafile) &&
1492                         !strequal(driver->helpfile, driver->configfile)) {
1493                         slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->helpfile);        
1494                         slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->helpfile);     
1495                         if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1496                                 NTSTATUS status;
1497                                 status = rename_internals(conn, new_name, old_name, True);
1498                                 if (!NT_STATUS_IS_OK(status)) {
1499                                         DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1500                                                         new_name, old_name));
1501                                         *perr = ntstatus_to_werror(status);
1502                                         unlink_internals(conn, 0, new_name);
1503                                         ver = -1;
1504                                 }
1505                         }
1506                         else
1507                                 unlink_internals(conn, 0, new_name);
1508                 }
1509         }
1510
1511         if (driver->dependentfiles) {
1512                 for (i=0; *driver->dependentfiles[i]; i++) {
1513                         if (!strequal(driver->dependentfiles[i], driver->driverpath) &&
1514                                 !strequal(driver->dependentfiles[i], driver->datafile) &&
1515                                 !strequal(driver->dependentfiles[i], driver->configfile) &&
1516                                 !strequal(driver->dependentfiles[i], driver->helpfile)) {
1517                                 int j;
1518                                 for (j=0; j < i; j++) {
1519                                         if (strequal(driver->dependentfiles[i], driver->dependentfiles[j])) {
1520                                                 goto NextDriver;
1521                                         }
1522                                 }
1523
1524                                 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->dependentfiles[i]);       
1525                                 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->dependentfiles[i]);    
1526                                 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1527                                         NTSTATUS status;
1528                                         status = rename_internals(conn, new_name, old_name, True);
1529                                         if (!NT_STATUS_IS_OK(status)) {
1530                                                 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1531                                                                 new_name, old_name));
1532                                                 *perr = ntstatus_to_werror(status);
1533                                                 unlink_internals(conn, 0, new_name);
1534                                                 ver = -1;
1535                                         }
1536                                 }
1537                                 else
1538                                         unlink_internals(conn, 0, new_name);
1539                         }
1540                 NextDriver: ;
1541                 }
1542         }
1543
1544         close_cnum(conn, user->vuid);
1545         unbecome_user();
1546
1547         return ver == -1 ? False : True;
1548 }
1549
1550 /****************************************************************************
1551 ****************************************************************************/
1552 static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
1553 {
1554         int len, buflen;
1555         fstring architecture;
1556         pstring directory;
1557         pstring temp_name;
1558         pstring key;
1559         char *buf;
1560         int i, ret;
1561         TDB_DATA kbuf, dbuf;
1562
1563         get_short_archi(architecture, driver->environment);
1564
1565         /* The names are relative. We store them in the form: \print$\arch\version\driver.xxx
1566          * \\server is added in the rpc server layer.
1567          * It does make sense to NOT store the server's name in the printer TDB.
1568          */
1569
1570         slprintf(directory, sizeof(directory)-1, "\\print$\\%s\\%d\\", architecture, driver->cversion);
1571
1572         /* .inf files do not always list a file for each of the four standard files. 
1573          * Don't prepend a path to a null filename, or client claims:
1574          *   "The server on which the printer resides does not have a suitable 
1575          *   <printer driver name> printer driver installed. Click OK if you 
1576          *   wish to install the driver on your local machine."
1577          */
1578         if (strlen(driver->driverpath)) {
1579                 fstrcpy(temp_name, driver->driverpath);
1580                 slprintf(driver->driverpath, sizeof(driver->driverpath)-1, "%s%s", directory, temp_name);
1581         }
1582
1583         if (strlen(driver->datafile)) {
1584                 fstrcpy(temp_name, driver->datafile);
1585                 slprintf(driver->datafile, sizeof(driver->datafile)-1, "%s%s", directory, temp_name);
1586         }
1587
1588         if (strlen(driver->configfile)) {
1589                 fstrcpy(temp_name, driver->configfile);
1590                 slprintf(driver->configfile, sizeof(driver->configfile)-1, "%s%s", directory, temp_name);
1591         }
1592
1593         if (strlen(driver->helpfile)) {
1594                 fstrcpy(temp_name, driver->helpfile);
1595                 slprintf(driver->helpfile, sizeof(driver->helpfile)-1, "%s%s", directory, temp_name);
1596         }
1597
1598         if (driver->dependentfiles) {
1599                 for (i=0; *driver->dependentfiles[i]; i++) {
1600                         fstrcpy(temp_name, driver->dependentfiles[i]);
1601                         slprintf(driver->dependentfiles[i], sizeof(driver->dependentfiles[i])-1, "%s%s", directory, temp_name);
1602                 }
1603         }
1604
1605         slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, driver->cversion, driver->name);
1606
1607         DEBUG(5,("add_a_printer_driver_3: Adding driver with key %s\n", key ));
1608
1609         buf = NULL;
1610         len = buflen = 0;
1611
1612  again:
1613         len = 0;
1614         len += tdb_pack(buf+len, buflen-len, "dffffffff",
1615                         driver->cversion,
1616                         driver->name,
1617                         driver->environment,
1618                         driver->driverpath,
1619                         driver->datafile,
1620                         driver->configfile,
1621                         driver->helpfile,
1622                         driver->monitorname,
1623                         driver->defaultdatatype);
1624
1625         if (driver->dependentfiles) {
1626                 for (i=0; *driver->dependentfiles[i]; i++) {
1627                         len += tdb_pack(buf+len, buflen-len, "f",
1628                                         driver->dependentfiles[i]);
1629                 }
1630         }
1631
1632         if (len != buflen) {
1633                 char *tb;
1634
1635                 tb = (char *)Realloc(buf, len);
1636                 if (!tb) {
1637                         DEBUG(0,("add_a_printer_driver_3: failed to enlarge buffer\n!"));
1638                         ret = -1;
1639                         goto done;
1640                 }
1641                 else buf = tb;
1642                 buflen = len;
1643                 goto again;
1644         }
1645
1646
1647         kbuf.dptr = key;
1648         kbuf.dsize = strlen(key)+1;
1649         dbuf.dptr = buf;
1650         dbuf.dsize = len;
1651         
1652         ret = tdb_store(tdb_drivers, kbuf, dbuf, TDB_REPLACE);
1653
1654 done:
1655         if (ret)
1656                 DEBUG(0,("add_a_printer_driver_3: Adding driver with key %s failed.\n", key ));
1657
1658         SAFE_FREE(buf);
1659         return ret;
1660 }
1661
1662 /****************************************************************************
1663 ****************************************************************************/
1664 static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
1665 {
1666         NT_PRINTER_DRIVER_INFO_LEVEL_3 info3;
1667
1668         ZERO_STRUCT(info3);
1669         info3.cversion = driver->version;
1670         fstrcpy(info3.name,driver->name);
1671         fstrcpy(info3.environment,driver->environment);
1672         fstrcpy(info3.driverpath,driver->driverpath);
1673         fstrcpy(info3.datafile,driver->datafile);
1674         fstrcpy(info3.configfile,driver->configfile);
1675         fstrcpy(info3.helpfile,driver->helpfile);
1676         fstrcpy(info3.monitorname,driver->monitorname);
1677         fstrcpy(info3.defaultdatatype,driver->defaultdatatype);
1678         info3.dependentfiles = driver->dependentfiles;
1679
1680         return add_a_printer_driver_3(&info3);
1681 }
1682
1683
1684 /****************************************************************************
1685 ****************************************************************************/
1686 static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
1687 {
1688         NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
1689
1690         ZERO_STRUCT(info);
1691
1692         fstrcpy(info.name, in_prt);
1693         fstrcpy(info.defaultdatatype, "RAW");
1694         
1695         fstrcpy(info.driverpath, "");
1696         fstrcpy(info.datafile, "");
1697         fstrcpy(info.configfile, "");
1698         fstrcpy(info.helpfile, "");
1699
1700         if ((info.dependentfiles=(fstring *)malloc(2*sizeof(fstring))) == NULL)
1701                 return WERR_NOMEM;
1702
1703         memset(info.dependentfiles, '\0', 2*sizeof(fstring));
1704         fstrcpy(info.dependentfiles[0], "");
1705
1706         *info_ptr = memdup(&info, sizeof(info));
1707         
1708         return WERR_OK;
1709 }
1710
1711 /****************************************************************************
1712 ****************************************************************************/
1713 static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch, uint32 version)
1714 {
1715         NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
1716         TDB_DATA kbuf, dbuf;
1717         fstring architecture;
1718         int len = 0;
1719         int i;
1720         pstring key;
1721
1722         ZERO_STRUCT(driver);
1723
1724         get_short_archi(architecture, in_arch);
1725
1726         DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, in_prt));
1727
1728         slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, in_prt);
1729
1730         kbuf.dptr = key;
1731         kbuf.dsize = strlen(key)+1;
1732         
1733         dbuf = tdb_fetch(tdb_drivers, kbuf);
1734 #if 0
1735         if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
1736 #else
1737         if (!dbuf.dptr) return WERR_ACCESS_DENIED;
1738 #endif
1739         len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff",
1740                           &driver.cversion,
1741                           driver.name,
1742                           driver.environment,
1743                           driver.driverpath,
1744                           driver.datafile,
1745                           driver.configfile,
1746                           driver.helpfile,
1747                           driver.monitorname,
1748                           driver.defaultdatatype);
1749
1750         i=0;
1751         while (len < dbuf.dsize) {
1752                 fstring *tddfs;
1753
1754                 tddfs = (fstring *)Realloc(driver.dependentfiles,
1755                                                          sizeof(fstring)*(i+2));
1756                 if (tddfs == NULL) {
1757                         DEBUG(0,("get_a_printer_driver_3: failed to enlarge buffer!\n"));
1758                         break;
1759                 }
1760                 else driver.dependentfiles = tddfs;
1761
1762                 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f",
1763                                   &driver.dependentfiles[i]);
1764                 i++;
1765         }
1766         if (driver.dependentfiles != NULL)
1767                 fstrcpy(driver.dependentfiles[i], "");
1768
1769         SAFE_FREE(dbuf.dptr);
1770
1771         if (len != dbuf.dsize) {
1772                         SAFE_FREE(driver.dependentfiles);
1773
1774                 return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
1775         }
1776
1777         *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
1778
1779         return WERR_OK;
1780 }
1781
1782 /****************************************************************************
1783 ****************************************************************************/
1784 uint32 get_a_printer_driver_9x_compatible(pstring line, fstring model)
1785 {
1786         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1787         TDB_DATA kbuf;
1788         pstring key;
1789         int i;
1790         line[0] = '\0';
1791
1792         slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, "WIN40", 0, model);
1793         DEBUG(10,("driver key: [%s]\n", key));
1794         
1795         kbuf.dptr = key;
1796         kbuf.dsize = strlen(key)+1;
1797         if (!tdb_exists(tdb_drivers, kbuf))
1798                 return False;
1799
1800         ZERO_STRUCT(info3);
1801         get_a_printer_driver_3(&info3, model, "Windows 4.0", 0);
1802         
1803         DEBUGADD(10,("info3->name            [%s]\n", info3->name));
1804         DEBUGADD(10,("info3->datafile        [%s]\n", info3->datafile));
1805         DEBUGADD(10,("info3->helpfile        [%s]\n", info3->helpfile));
1806         DEBUGADD(10,("info3->monitorname     [%s]\n", info3->monitorname));
1807         DEBUGADD(10,("info3->defaultdatatype [%s]\n", info3->defaultdatatype));
1808         for (i=0; info3->dependentfiles && *info3->dependentfiles[i]; i++) {
1809                 DEBUGADD(10,("info3->dependentfiles  [%s]\n", info3->dependentfiles[i]));
1810         }
1811         DEBUGADD(10,("info3->environment     [%s]\n", info3->environment));
1812         DEBUGADD(10,("info3->driverpath      [%s]\n", info3->driverpath));
1813         DEBUGADD(10,("info3->configfile      [%s]\n", info3->configfile));
1814
1815         /*pstrcat(line, info3->name);             pstrcat(line, ":");*/
1816         trim_string(info3->driverpath, "\\print$\\WIN40\\0\\", 0);
1817         pstrcat(line, info3->driverpath);
1818         pstrcat(line, ":");
1819         trim_string(info3->datafile, "\\print$\\WIN40\\0\\", 0);
1820         pstrcat(line, info3->datafile);
1821         pstrcat(line, ":");
1822         trim_string(info3->helpfile, "\\print$\\WIN40\\0\\", 0);
1823         pstrcat(line, info3->helpfile);
1824         pstrcat(line, ":");
1825         trim_string(info3->monitorname, "\\print$\\WIN40\\0\\", 0);
1826         pstrcat(line, info3->monitorname);
1827         pstrcat(line, ":");
1828         pstrcat(line, "RAW");                /*info3->defaultdatatype);*/
1829         pstrcat(line, ":");
1830
1831         for (i=0; info3->dependentfiles && *info3->dependentfiles[i]; i++) {
1832                 if (i)
1833                         pstrcat(line, ",");               /* don't end in a "," */
1834                 trim_string(info3->dependentfiles[i], "\\print$\\WIN40\\0\\", 0);
1835                 pstrcat(line, info3->dependentfiles[i]);
1836         }
1837         
1838         SAFE_FREE(info3);
1839
1840         return True;    
1841 }
1842
1843 /****************************************************************************
1844  Debugging function, dump at level 6 the struct in the logs.
1845 ****************************************************************************/
1846
1847 static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1848 {
1849         uint32 result;
1850         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1851         int i;
1852         
1853         DEBUG(106,("Dumping printer driver at level [%d]\n", level));
1854         
1855         switch (level)
1856         {
1857                 case 3:
1858                 {
1859                         if (driver.info_3 == NULL)
1860                                 result=5;
1861                         else {
1862                                 info3=driver.info_3;
1863                         
1864                                 DEBUGADD(106,("version:[%d]\n",         info3->cversion));
1865                                 DEBUGADD(106,("name:[%s]\n",            info3->name));
1866                                 DEBUGADD(106,("environment:[%s]\n",     info3->environment));
1867                                 DEBUGADD(106,("driverpath:[%s]\n",      info3->driverpath));
1868                                 DEBUGADD(106,("datafile:[%s]\n",        info3->datafile));
1869                                 DEBUGADD(106,("configfile:[%s]\n",      info3->configfile));
1870                                 DEBUGADD(106,("helpfile:[%s]\n",        info3->helpfile));
1871                                 DEBUGADD(106,("monitorname:[%s]\n",     info3->monitorname));
1872                                 DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
1873                                 
1874                                 for (i=0; info3->dependentfiles &&
1875                                           *info3->dependentfiles[i]; i++) {
1876                                         DEBUGADD(106,("dependentfile:[%s]\n",
1877                                                       info3->dependentfiles[i]));
1878                                 }
1879                                 result=0;
1880                         }
1881                         break;
1882                 }
1883                 default:
1884                         DEBUGADD(106,("dump_a_printer_driver: Level %u not implemented\n", (unsigned int)level));
1885                         result=1;
1886                         break;
1887         }
1888         
1889         return result;
1890 }
1891
1892 /****************************************************************************
1893 ****************************************************************************/
1894 static int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
1895 {
1896         int len = 0;
1897
1898         len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
1899
1900         if (!nt_devmode) return len;
1901
1902         len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
1903                         nt_devmode->devicename,
1904                         nt_devmode->formname,
1905
1906                         nt_devmode->specversion,
1907                         nt_devmode->driverversion,
1908                         nt_devmode->size,
1909                         nt_devmode->driverextra,
1910                         nt_devmode->orientation,
1911                         nt_devmode->papersize,
1912                         nt_devmode->paperlength,
1913                         nt_devmode->paperwidth,
1914                         nt_devmode->scale,
1915                         nt_devmode->copies,
1916                         nt_devmode->defaultsource,
1917                         nt_devmode->printquality,
1918                         nt_devmode->color,
1919                         nt_devmode->duplex,
1920                         nt_devmode->yresolution,
1921                         nt_devmode->ttoption,
1922                         nt_devmode->collate,
1923                         nt_devmode->logpixels,
1924                         
1925                         nt_devmode->fields,
1926                         nt_devmode->bitsperpel,
1927                         nt_devmode->pelswidth,
1928                         nt_devmode->pelsheight,
1929                         nt_devmode->displayflags,
1930                         nt_devmode->displayfrequency,
1931                         nt_devmode->icmmethod,
1932                         nt_devmode->icmintent,
1933                         nt_devmode->mediatype,
1934                         nt_devmode->dithertype,
1935                         nt_devmode->reserved1,
1936                         nt_devmode->reserved2,
1937                         nt_devmode->panningwidth,
1938                         nt_devmode->panningheight,
1939                         nt_devmode->private);
1940
1941         
1942         if (nt_devmode->private) {
1943                 len += tdb_pack(buf+len, buflen-len, "B",
1944                                 nt_devmode->driverextra,
1945                                 nt_devmode->private);
1946         }
1947
1948         DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname));
1949
1950         return len;
1951 }
1952
1953 /****************************************************************************
1954 ****************************************************************************/
1955 static int pack_specifics(NT_PRINTER_PARAM *param, char *buf, int buflen)
1956 {
1957         int len = 0;
1958
1959         while (param != NULL) {
1960                 len += tdb_pack(buf+len, buflen-len, "pfdB",
1961                                 param,
1962                                 param->value,
1963                                 param->type,
1964                                 param->data_len,
1965                                 param->data);
1966                 param=param->next;      
1967         }
1968
1969         len += tdb_pack(buf+len, buflen-len, "p", param);
1970
1971         return len;
1972 }
1973
1974
1975 /****************************************************************************
1976  Delete a printer - this just deletes the printer info file, any open
1977  handles are not affected.
1978 ****************************************************************************/
1979
1980 uint32 del_a_printer(char *sharename)
1981 {
1982         pstring key;
1983         TDB_DATA kbuf;
1984
1985         slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
1986
1987         kbuf.dptr=key;
1988         kbuf.dsize=strlen(key)+1;
1989
1990         tdb_delete(tdb_printers, kbuf);
1991         return 0;
1992 }
1993
1994 /* FIXME!!!  Reorder so this forward declaration is not necessary --jerry */
1995 static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **, fstring);
1996 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **);
1997 /****************************************************************************
1998 ****************************************************************************/
1999 static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
2000 {
2001         pstring key;
2002         char *buf;
2003         int buflen, len;
2004         WERROR ret;
2005         TDB_DATA kbuf, dbuf;
2006         
2007         /*
2008          * in addprinter: no servername and the printer is the name
2009          * in setprinter: servername is \\server
2010          *                and printer is \\server\\printer
2011          *
2012          * Samba manages only local printers.
2013          * we currently don't support things like path=\\other_server\printer
2014          */
2015
2016         if (info->servername[0]!='\0') {
2017                 trim_string(info->printername, info->servername, NULL);
2018                 trim_string(info->printername, "\\", NULL);
2019                 info->servername[0]='\0';
2020         }
2021
2022         /*
2023          * JFM: one day I'll forget.
2024          * below that's info->portname because that's the SAMBA sharename
2025          * and I made NT 'thinks' it's the portname
2026          * the info->sharename is the thing you can name when you add a printer
2027          * that's the short-name when you create shared printer for 95/98
2028          * So I've made a limitation in SAMBA: you can only have 1 printer model
2029          * behind a SAMBA share.
2030          */
2031
2032         buf = NULL;
2033         buflen = 0;
2034
2035  again: 
2036         len = 0;
2037         len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffPfffff",
2038                         info->attributes,
2039                         info->priority,
2040                         info->default_priority,
2041                         info->starttime,
2042                         info->untiltime,
2043                         info->status,
2044                         info->cjobs,
2045                         info->averageppm,
2046                         info->changeid,
2047                         info->c_setprinter,
2048                         info->setuptime,
2049                         info->servername,
2050                         info->printername,
2051                         info->sharename,
2052                         info->portname,
2053                         info->drivername,
2054                         info->comment,
2055                         info->location,
2056                         info->sepfile,
2057                         info->printprocessor,
2058                         info->datatype,
2059                         info->parameters);
2060
2061         len += pack_devicemode(info->devmode, buf+len, buflen-len);
2062         
2063         len += pack_specifics(info->specific, buf+len, buflen-len);
2064
2065         if (buflen != len) {
2066                 char *tb;
2067
2068                 tb = (char *)Realloc(buf, len);
2069                 if (!tb) {
2070                         DEBUG(0,("update_a_printer_2: failed to enlarge buffer!\n"));
2071                         ret = WERR_NOMEM;
2072                         goto done;
2073                 }
2074                 else buf = tb;
2075                 buflen = len;
2076                 goto again;
2077         }
2078         
2079
2080         slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, info->sharename);
2081
2082         kbuf.dptr = key;
2083         kbuf.dsize = strlen(key)+1;
2084         dbuf.dptr = buf;
2085         dbuf.dsize = len;
2086
2087         ret = (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) == 0? WERR_OK : WERR_NOMEM);
2088
2089 done:
2090         if (!W_ERROR_IS_OK(ret))
2091                 DEBUG(8, ("error updating printer to tdb on disk\n"));
2092
2093         SAFE_FREE(buf);
2094
2095         DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n",
2096                  info->sharename, info->drivername, info->portname, len));
2097
2098         return ret;
2099 }
2100
2101
2102 /****************************************************************************
2103 ****************************************************************************/
2104 void add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM **param)
2105 {
2106         NT_PRINTER_PARAM *current;
2107         
2108         DEBUG(108,("add_a_specific_param\n"));  
2109
2110         (*param)->next=NULL;
2111         
2112         if (info_2->specific == NULL)
2113         {
2114                 info_2->specific=*param;
2115         }
2116         else
2117         {
2118                 current=info_2->specific;               
2119                 while (current->next != NULL) {
2120                         current=current->next;
2121                 }               
2122                 current->next=*param;
2123         }
2124
2125         *param = NULL;
2126 }
2127
2128 /****************************************************************************
2129 ****************************************************************************/
2130 BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
2131 {
2132         NT_PRINTER_PARAM *current;
2133         NT_PRINTER_PARAM *previous;
2134         
2135         current=info_2->specific;
2136         previous=current;
2137         
2138         if (current==NULL) return (False);
2139         
2140         if ( !strcmp(current->value, param->value) &&
2141             (strlen(current->value)==strlen(param->value)) ) {
2142                 DEBUG(109,("deleting first value\n"));
2143                 info_2->specific=current->next;
2144                 SAFE_FREE(current->data);
2145                 SAFE_FREE(current);
2146                 DEBUG(109,("deleted first value\n"));
2147                 return (True);
2148         }
2149
2150         current=previous->next;
2151                 
2152         while ( current!=NULL ) {
2153                 if (!strcmp(current->value, param->value) &&
2154                     strlen(current->value)==strlen(param->value) ) {
2155                         DEBUG(109,("deleting current value\n"));
2156                         previous->next=current->next;
2157                         SAFE_FREE(current->data);
2158                         SAFE_FREE(current);
2159                         DEBUG(109,("deleted current value\n"));
2160                         return(True);
2161                 }
2162                 
2163                 previous=previous->next;
2164                 current=current->next;
2165         }
2166         return (False);
2167 }
2168
2169 /****************************************************************************
2170  Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
2171 ****************************************************************************/
2172 void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr)
2173 {
2174         NT_PRINTER_PARAM *param = *param_ptr;
2175
2176         if(param == NULL)
2177                 return;
2178
2179         DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param->value));
2180
2181                 SAFE_FREE(param->data);
2182         SAFE_FREE(*param_ptr);
2183 }
2184
2185 /****************************************************************************
2186  Malloc and return an NT devicemode.
2187 ****************************************************************************/
2188
2189 NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
2190 {
2191
2192         char adevice[32];
2193         NT_DEVICEMODE *nt_devmode = (NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE));
2194
2195         if (nt_devmode == NULL) {
2196                 DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
2197                 return NULL;
2198         }
2199
2200         ZERO_STRUCTP(nt_devmode);
2201
2202         safe_strcpy(adevice, default_devicename, sizeof(adevice));
2203         fstrcpy(nt_devmode->devicename, adevice);       
2204         
2205         fstrcpy(nt_devmode->formname, "Letter");
2206
2207         nt_devmode->specversion      = 0x0401;
2208         nt_devmode->driverversion    = 0x0400;
2209         nt_devmode->size             = 0x00DC;
2210         nt_devmode->driverextra      = 0x0000;
2211         nt_devmode->fields           = FORMNAME | TTOPTION | PRINTQUALITY |
2212                                        DEFAULTSOURCE | COPIES | SCALE |
2213                                        PAPERSIZE | ORIENTATION;
2214         nt_devmode->orientation      = 1;
2215         nt_devmode->papersize        = PAPER_LETTER;
2216         nt_devmode->paperlength      = 0;
2217         nt_devmode->paperwidth       = 0;
2218         nt_devmode->scale            = 0x64;
2219         nt_devmode->copies           = 1;
2220         nt_devmode->defaultsource    = BIN_FORMSOURCE;
2221         nt_devmode->printquality     = RES_HIGH;           /* 0x0258 */
2222         nt_devmode->color            = COLOR_MONOCHROME;
2223         nt_devmode->duplex           = DUP_SIMPLEX;
2224         nt_devmode->yresolution      = 0;
2225         nt_devmode->ttoption         = TT_SUBDEV;
2226         nt_devmode->collate          = COLLATE_FALSE;
2227         nt_devmode->icmmethod        = 0;
2228         nt_devmode->icmintent        = 0;
2229         nt_devmode->mediatype        = 0;
2230         nt_devmode->dithertype       = 0;
2231
2232         /* non utilisés par un driver d'imprimante */
2233         nt_devmode->logpixels        = 0;
2234         nt_devmode->bitsperpel       = 0;
2235         nt_devmode->pelswidth        = 0;
2236         nt_devmode->pelsheight       = 0;
2237         nt_devmode->displayflags     = 0;
2238         nt_devmode->displayfrequency = 0;
2239         nt_devmode->reserved1        = 0;
2240         nt_devmode->reserved2        = 0;
2241         nt_devmode->panningwidth     = 0;
2242         nt_devmode->panningheight    = 0;
2243         
2244         nt_devmode->private = NULL;
2245         return nt_devmode;
2246 }
2247
2248 /****************************************************************************
2249  Deepcopy an NT devicemode.
2250 ****************************************************************************/
2251
2252 NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
2253 {
2254         NT_DEVICEMODE *new_nt_devicemode = NULL;
2255
2256         if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
2257                 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
2258                 return NULL;
2259         }
2260
2261         new_nt_devicemode->private = NULL;
2262         if (nt_devicemode->private != NULL) {
2263                 if ((new_nt_devicemode->private = memdup(nt_devicemode->private, nt_devicemode->driverextra)) == NULL) {
2264                         SAFE_FREE(new_nt_devicemode);
2265                         DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
2266                         return NULL;
2267         }
2268         }
2269
2270         return new_nt_devicemode;
2271 }
2272
2273 /****************************************************************************
2274  Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
2275 ****************************************************************************/
2276
2277 void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
2278 {
2279         NT_DEVICEMODE *nt_devmode = *devmode_ptr;
2280
2281         if(nt_devmode == NULL)
2282                 return;
2283
2284         DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
2285
2286                 SAFE_FREE(nt_devmode->private);
2287         SAFE_FREE(*devmode_ptr);
2288 }
2289
2290 /****************************************************************************
2291  Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
2292 ****************************************************************************/
2293 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
2294 {
2295         NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
2296         NT_PRINTER_PARAM *param_ptr;
2297
2298         if(info == NULL)
2299                 return;
2300
2301         DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
2302
2303         free_nt_devicemode(&info->devmode);
2304
2305         for(param_ptr = info->specific; param_ptr; ) {
2306                 NT_PRINTER_PARAM *tofree = param_ptr;
2307
2308                 param_ptr = param_ptr->next;
2309                 free_nt_printer_param(&tofree);
2310         }
2311
2312         SAFE_FREE(*info_ptr);
2313 }
2314
2315
2316 /****************************************************************************
2317 ****************************************************************************/
2318 static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
2319 {
2320         int len = 0;
2321         int extra_len = 0;
2322         NT_DEVICEMODE devmode;
2323
2324         ZERO_STRUCT(devmode);
2325
2326         len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
2327
2328         if (!*nt_devmode) return len;
2329
2330         len += tdb_unpack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
2331                           devmode.devicename,
2332                           devmode.formname,
2333
2334                           &devmode.specversion,
2335                           &devmode.driverversion,
2336                           &devmode.size,
2337                           &devmode.driverextra,
2338                           &devmode.orientation,
2339                           &devmode.papersize,
2340                           &devmode.paperlength,
2341                           &devmode.paperwidth,
2342                           &devmode.scale,
2343                           &devmode.copies,
2344                           &devmode.defaultsource,
2345                           &devmode.printquality,
2346                           &devmode.color,
2347                           &devmode.duplex,
2348                           &devmode.yresolution,
2349                           &devmode.ttoption,
2350                           &devmode.collate,
2351                           &devmode.logpixels,
2352                         
2353                           &devmode.fields,
2354                           &devmode.bitsperpel,
2355                           &devmode.pelswidth,
2356                           &devmode.pelsheight,
2357                           &devmode.displayflags,
2358                           &devmode.displayfrequency,
2359                           &devmode.icmmethod,
2360                           &devmode.icmintent,
2361                           &devmode.mediatype,
2362                           &devmode.dithertype,
2363                           &devmode.reserved1,
2364                           &devmode.reserved2,
2365                           &devmode.panningwidth,
2366                           &devmode.panningheight,
2367                           &devmode.private);
2368         
2369         if (devmode.private) {
2370                 /* the len in tdb_unpack is an int value and
2371                  * devmode.driverextra is only a short
2372                  */
2373                 len += tdb_unpack(buf+len, buflen-len, "B", &extra_len, &devmode.private);
2374                 devmode.driverextra=(uint16)extra_len;
2375                 
2376                 /* check to catch an invalid TDB entry so we don't segfault */
2377                 if (devmode.driverextra == 0) {
2378                         devmode.private = NULL;
2379                 }
2380         }
2381
2382         *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
2383
2384         DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode.devicename, devmode.formname));
2385         if (devmode.private)
2386                 DEBUG(8,("with a private section of %d bytes\n", devmode.driverextra));
2387
2388         return len;
2389 }
2390
2391 /****************************************************************************
2392 ****************************************************************************/
2393 static int unpack_specifics(NT_PRINTER_PARAM **list, char *buf, int buflen)
2394 {
2395         int len = 0;
2396         NT_PRINTER_PARAM param, *p;
2397
2398         *list = NULL;
2399
2400         while (1) {
2401                 len += tdb_unpack(buf+len, buflen-len, "p", &p);
2402                 if (!p) break;
2403
2404                 len += tdb_unpack(buf+len, buflen-len, "fdB",
2405                                   param.value,
2406                                   &param.type,
2407                                   &param.data_len,
2408                                   &param.data);
2409                 param.next = *list;
2410                 *list = memdup(&param, sizeof(param));
2411
2412                 DEBUG(8,("specific: [%s], len: %d\n", param.value, param.data_len));
2413         }
2414
2415         return len;
2416 }
2417
2418 static void map_to_os2_driver(fstring drivername)
2419 {
2420         static BOOL initialised=False;
2421         static fstring last_from,last_to;
2422         char *mapfile = lp_os2_driver_map();
2423         char **lines = NULL;
2424         int numlines = 0;
2425         int i;
2426
2427         if (!strlen(drivername))
2428                 return;
2429
2430         if (!*mapfile)
2431                 return;
2432
2433         if (!initialised) {
2434                 *last_from = *last_to = 0;
2435                 initialised = True;
2436         }
2437
2438         if (strequal(drivername,last_from)) {
2439                 DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",drivername,last_to));
2440                 fstrcpy(drivername,last_to);
2441                 return;
2442         }
2443
2444         lines = file_lines_load(mapfile, &numlines);
2445         if (numlines == 0) {
2446                 DEBUG(0,("No entries in OS/2 driver map %s\n",mapfile));
2447                 return;
2448         }
2449
2450         DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile));
2451
2452         for( i = 0; i < numlines; i++) {
2453                 char *nt_name = lines[i];
2454                 char *os2_name = strchr(nt_name,'=');
2455
2456                 if (!os2_name)
2457                         continue;
2458
2459                 *os2_name++ = 0;
2460
2461                 while (isspace(*nt_name))
2462                         nt_name++;
2463
2464                 if (!*nt_name || strchr("#;",*nt_name))
2465                         continue;
2466
2467                 {
2468                         int l = strlen(nt_name);
2469                         while (l && isspace(nt_name[l-1])) {
2470                                 nt_name[l-1] = 0;
2471                                 l--;
2472                         }
2473                 }
2474
2475                 while (isspace(*os2_name))
2476                         os2_name++;
2477
2478                 {
2479                         int l = strlen(os2_name);
2480                         while (l && isspace(os2_name[l-1])) {
2481                                 os2_name[l-1] = 0;
2482                                 l--;
2483                         }
2484                 }
2485
2486                 if (strequal(nt_name,drivername)) {
2487                         DEBUG(3,("Mapped windows driver %s to os2 driver%s\n",drivername,os2_name));
2488                         fstrcpy(last_from,drivername);
2489                         fstrcpy(last_to,os2_name);
2490                         fstrcpy(drivername,os2_name);
2491                         file_lines_free(lines);
2492                         return;
2493                 }
2494         }
2495
2496         file_lines_free(lines);
2497 }
2498
2499 /****************************************************************************
2500 get a default printer info 2 struct
2501 ****************************************************************************/
2502 static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
2503 {
2504         int snum;
2505         NT_PRINTER_INFO_LEVEL_2 info;
2506
2507         ZERO_STRUCT(info);
2508
2509         snum = lp_servicenumber(sharename);
2510
2511         slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", get_called_name());
2512         slprintf(info.printername, sizeof(info.printername)-1, "\\\\%s\\%s", 
2513                  get_called_name(), sharename);
2514         fstrcpy(info.sharename, sharename);
2515         fstrcpy(info.portname, SAMBA_PRINTER_PORT_NAME);
2516         fstrcpy(info.drivername, lp_printerdriver(snum));
2517
2518         /* by setting the driver name to an empty string, a local NT admin
2519            can now run the **local** APW to install a local printer driver
2520            for a Samba shared printer in 2.2.  Without this, drivers **must** be 
2521            installed on the Samba server for NT clients --jerry */
2522 #if 0   /* JERRY --do not uncomment-- */
2523         if (!*info.drivername)
2524                 fstrcpy(info.drivername, "NO DRIVER AVAILABLE FOR THIS PRINTER");
2525 #endif
2526
2527
2528         DEBUG(10,("get_a_printer_2_default: driver name set to [%s]\n", info.drivername));
2529
2530         pstrcpy(info.comment, "");
2531         fstrcpy(info.printprocessor, "winprint");
2532         fstrcpy(info.datatype, "RAW");
2533
2534         info.attributes = PRINTER_ATTRIBUTE_SHARED | PRINTER_ATTRIBUTE_NETWORK;      /* attributes */
2535
2536         info.starttime = 0; /* Minutes since 12:00am GMT */
2537         info.untiltime = 0; /* Minutes since 12:00am GMT */
2538         info.priority = 1;
2539         info.default_priority = 1;
2540         info.setuptime = (uint32)time(NULL);
2541
2542         /*
2543          * I changed this as I think it is better to have a generic
2544          * DEVMODE than to crash Win2k explorer.exe   --jerry
2545          * See the HP Deskjet 990c Win2k drivers for an example.
2546          *
2547          * However the default devmode appears to cause problems
2548          * with the HP CLJ 8500 PCL driver.  Hence the addition of
2549          * the "default devmode" parameter   --jerry 22/01/2002
2550          */
2551
2552         if (lp_default_devmode(snum)) {
2553                 if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
2554                         goto fail;
2555         }
2556         else {
2557                 info.devmode = NULL;
2558         }
2559
2560         /* This will get the current RPC talloc context, but we should be
2561            passing this as a parameter... fixme... JRA ! */
2562
2563         if (!nt_printing_getsec(get_talloc_ctx(), sharename, &info.secdesc_buf))
2564                 goto fail;
2565
2566         *info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
2567         if (! *info_ptr) {
2568                 DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
2569                 goto fail;
2570         }
2571
2572         return WERR_OK;
2573
2574   fail:
2575         if (info.devmode)
2576                 free_nt_devicemode(&info.devmode);
2577         return WERR_ACCESS_DENIED;
2578 }
2579
2580 /****************************************************************************
2581 ****************************************************************************/
2582 static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
2583 {
2584         pstring key;
2585         NT_PRINTER_INFO_LEVEL_2 info;
2586         int             len = 0;
2587         TDB_DATA kbuf, dbuf;
2588         fstring printername;
2589                 
2590         ZERO_STRUCT(info);
2591
2592         slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
2593
2594         kbuf.dptr = key;
2595         kbuf.dsize = strlen(key)+1;
2596
2597         dbuf = tdb_fetch(tdb_printers, kbuf);
2598         if (!dbuf.dptr)
2599                 return get_a_printer_2_default(info_ptr, sharename);
2600
2601         len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff",
2602                         &info.attributes,
2603                         &info.priority,
2604                         &info.default_priority,
2605                         &info.starttime,
2606                         &info.untiltime,
2607                         &info.status,
2608                         &info.cjobs,
2609                         &info.averageppm,
2610                         &info.changeid,
2611                         &info.c_setprinter,
2612                         &info.setuptime,
2613                         info.servername,
2614                         info.printername,
2615                         info.sharename,
2616                         info.portname,
2617                         info.drivername,
2618                         info.comment,
2619                         info.location,
2620                         info.sepfile,
2621                         info.printprocessor,
2622                         info.datatype,
2623                         info.parameters);
2624
2625         /* Samba has to have shared raw drivers. */
2626         info.attributes |= (PRINTER_ATTRIBUTE_SHARED | PRINTER_ATTRIBUTE_NETWORK); 
2627
2628         /* Restore the stripped strings. */
2629         slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", get_called_name());
2630         slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", get_called_name(),
2631                         info.printername);
2632         fstrcpy(info.printername, printername);
2633
2634         len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
2635
2636         /*
2637          * Some client drivers freak out if there is a NULL devmode
2638          * (probably the driver is not checking before accessing 
2639          * the devmode pointer)   --jerry
2640          *
2641          * See comments in get_a_printer_2_default()
2642          */
2643
2644         if (lp_default_devmode(lp_servicenumber(sharename)) && !info.devmode)
2645         {
2646                 DEBUG(8,("get_a_printer_2: Constructing a default device mode for [%s]\n",
2647                         printername));
2648                 info.devmode = construct_nt_devicemode(printername);
2649         }
2650
2651         len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
2652
2653         /* This will get the current RPC talloc context, but we should be
2654        passing this as a parameter... fixme... JRA ! */
2655
2656         nt_printing_getsec(get_talloc_ctx(), sharename, &info.secdesc_buf);
2657
2658         /* Fix for OS/2 drivers. */
2659
2660         if (get_remote_arch() == RA_OS2)
2661                 map_to_os2_driver(info.drivername);
2662
2663         SAFE_FREE(dbuf.dptr);
2664         *info_ptr=memdup(&info, sizeof(info));
2665
2666         DEBUG(9,("Unpacked printer [%s] name [%s] running driver [%s]\n",
2667                  sharename, info.printername, info.drivername));
2668
2669         return WERR_OK; 
2670 }
2671
2672 /****************************************************************************
2673 debugging function, dump at level 6 the struct in the logs
2674 ****************************************************************************/
2675 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2676 {
2677         uint32 result;
2678         NT_PRINTER_INFO_LEVEL_2 *info2;
2679         
2680         DEBUG(106,("Dumping printer at level [%d]\n", level));
2681         
2682         switch (level)
2683         {
2684                 case 2:
2685                 {
2686                         if (printer.info_2 == NULL)
2687                                 result=5;
2688                         else
2689                         {
2690                                 info2=printer.info_2;
2691                         
2692                                 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
2693                                 DEBUGADD(106,("priority:[%d]\n", info2->priority));
2694                                 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
2695                                 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
2696                                 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
2697                                 DEBUGADD(106,("status:[%d]\n", info2->status));
2698                                 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
2699                                 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
2700                                 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
2701                                 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
2702                                 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
2703
2704                                 DEBUGADD(106,("servername:[%s]\n", info2->servername));
2705                                 DEBUGADD(106,("printername:[%s]\n", info2->printername));
2706                                 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
2707                                 DEBUGADD(106,("portname:[%s]\n", info2->portname));
2708                                 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
2709                                 DEBUGADD(106,("comment:[%s]\n", info2->comment));
2710                                 DEBUGADD(106,("location:[%s]\n", info2->location));
2711                                 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
2712                                 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
2713                                 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
2714                                 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
2715                                 result=0;
2716                         }
2717                         break;
2718                 }
2719                 default:
2720                         DEBUGADD(106,("dump_a_printer: Level %u not implemented\n", (unsigned int)level ));
2721                         result=1;
2722                         break;
2723         }
2724         
2725         return result;
2726 }
2727
2728 /****************************************************************************
2729  Get the parameters we can substitute in an NT print job.
2730 ****************************************************************************/
2731
2732 void get_printer_subst_params(int snum, fstring *printername, fstring *sharename, fstring *portname)
2733 {
2734         NT_PRINTER_INFO_LEVEL *printer = NULL;
2735
2736         **printername = **sharename = **portname = '\0';
2737
2738         if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
2739                 return;
2740
2741         fstrcpy(*printername, printer->info_2->printername);
2742         fstrcpy(*sharename, printer->info_2->sharename);
2743         fstrcpy(*portname, printer->info_2->portname);
2744
2745         free_a_printer(&printer, 2);
2746 }
2747
2748 /****************************************************************************
2749  Update the changeid time.
2750  This is SO NASTY as some drivers need this to change, others need it
2751  static. This value will change every second, and I must hope that this
2752  is enough..... DON'T CHANGE THIS CODE WITHOUT A TEST MATRIX THE SIZE OF
2753  UTAH ! JRA.
2754 ****************************************************************************/
2755
2756 static uint32 rev_changeid(void)
2757 {
2758         struct timeval tv;
2759
2760         get_process_uptime(&tv);
2761
2762 #if 1   /* JERRY */
2763         /* Return changeid as msec since spooler restart */
2764         return tv.tv_sec * 1000 + tv.tv_usec / 1000;
2765 #else
2766         /*
2767          * This setting seems to work well but is too untested
2768          * to replace the above calculation.  Left in for experiementation
2769          * of the reader            --jerry (Tue Mar 12 09:15:05 CST 2002)
2770          */
2771         return tv.tv_sec * 10 + tv.tv_usec / 100000;
2772 #endif
2773 }
2774
2775 /*
2776  * The function below are the high level ones.
2777  * only those ones must be called from the spoolss code.
2778  * JFM.
2779  */
2780
2781 /****************************************************************************
2782  Modify a printer. This is called from SETPRINTERDATA/DELETEPRINTERDATA.
2783 ****************************************************************************/
2784
2785 WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2786 {
2787         WERROR result;
2788         
2789         dump_a_printer(printer, level); 
2790         
2791         switch (level)
2792         {
2793                 case 2:
2794                 {
2795                         /*
2796                          * Update the changestamp.  Emperical tests show that the
2797                          * ChangeID is always updated,but c_setprinter is  
2798                          *  global spooler variable (not per printer).
2799                          */
2800
2801                         /* ChangeID **must** be increasing over the lifetime
2802                            of client's spoolss service in order for the
2803                            client's cache to show updates */
2804
2805                         printer.info_2->changeid = rev_changeid();
2806
2807                         /*
2808                          * Because one day someone will ask:
2809                          * NT->NT       An admin connection to a remote
2810                          *              printer show changes imeediately in
2811                          *              the properities dialog
2812                          *      
2813                          *              A non-admin connection will only show the
2814                          *              changes after viewing the properites page
2815                          *              2 times.  Seems to be related to a
2816                          *              race condition in the client between the spooler
2817                          *              updating the local cache and the Explorer.exe GUI
2818                          *              actually displaying the properties.
2819                          *
2820                          *              This is fixed in Win2k.  admin/non-admin
2821                          *              connections both display changes immediately.
2822                          *
2823                          * 14/12/01     --jerry
2824                          */
2825
2826                         result=update_a_printer_2(printer.info_2);
2827                         break;
2828                 }
2829                 default:
2830                         result=WERR_UNKNOWN_LEVEL;
2831                         break;
2832         }
2833         
2834         return result;
2835 }
2836
2837 /****************************************************************************
2838  Initialize printer devmode & data with previously saved driver init values.
2839 ****************************************************************************/
2840
2841 static uint32 set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr)
2842 {
2843         int                     len = 0;
2844         pstring                 key;
2845         TDB_DATA                kbuf, dbuf;
2846         NT_PRINTER_PARAM        *current;
2847         NT_PRINTER_INFO_LEVEL_2 info;
2848
2849         /*
2850          * Delete any printer data 'specifics' already set. When called for driver
2851          * replace, there will generally be some, but during an add printer, there
2852          * should not be any (if there are delete them).
2853          */
2854         while ( (current=info_ptr->specific) != NULL ) {
2855                 info_ptr->specific=current->next;
2856                 SAFE_FREE(current->data);
2857                 SAFE_FREE(current);
2858         }
2859
2860         ZERO_STRUCT(info);
2861
2862         slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info_ptr->drivername);
2863
2864         kbuf.dptr = key;
2865         kbuf.dsize = strlen(key)+1;
2866
2867         dbuf = tdb_fetch(tdb_drivers, kbuf);
2868     if (!dbuf.dptr) {
2869                 /*
2870                  * When changing to a driver that has no init info in the tdb, remove
2871                  * the previous drivers init info and leave the new on blank.
2872                  */
2873                 free_nt_devicemode(&info_ptr->devmode);
2874                 return False;
2875         }
2876
2877         /*
2878          * Get the saved DEVMODE..
2879          */
2880         len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
2881
2882         /*
2883          * The saved DEVMODE contains the devicename from the printer used during
2884          * the initialization save. Change it to reflect the new printer.
2885          */
2886         ZERO_STRUCT(info.devmode->devicename);
2887         fstrcpy(info.devmode->devicename, info_ptr->printername);
2888
2889
2890         /*
2891          * NT/2k does not change out the entire DeviceMode of a printer
2892          * when changing the driver.  Only the driverextra, private, & 
2893          * driverversion fields.   --jerry  (Thu Mar 14 08:58:43 CST 2002)
2894          */
2895
2896 #if 0   /* JERRY */
2897
2898         /* 
2899          *      Bind the saved DEVMODE to the new the printer.
2900          */
2901         free_nt_devicemode(&info_ptr->devmode);
2902         info_ptr->devmode = info.devmode;
2903 #else
2904         /* copy the entire devmode if we currently don't have one */
2905
2906         if (!info_ptr->devmode) {
2907                 DEBUG(10,("set_driver_init_2: Current Devmode is NULL.  Copying entire Device Mode\n"));
2908                 info_ptr->devmode = info.devmode;
2909         }
2910         else {
2911                 /* only set the necessary fields */
2912
2913                 DEBUG(10,("set_driver_init_2: Setting driverversion [0x%x] and private data [0x%x]\n",
2914                         info.devmode->driverversion, info.devmode->driverextra));
2915
2916                 info_ptr->devmode->driverversion = info.devmode->driverversion;
2917
2918                 SAFE_FREE(info_ptr->devmode->private);
2919                 info_ptr->devmode->private = NULL;
2920
2921                 if (info.devmode->driverversion)
2922                         info_ptr->devmode->private = memdup(info.devmode->private, info.devmode->driverversion);
2923
2924                 free_nt_devicemode(&info.devmode);
2925         }
2926 #endif
2927
2928         DEBUG(10,("set_driver_init_2: Set printer [%s] init DEVMODE for driver [%s]\n",
2929                         info_ptr->printername, info_ptr->drivername));
2930
2931         /* 
2932          * Add the printer data 'specifics' to the new printer
2933          */
2934         len += unpack_specifics(&info_ptr->specific,dbuf.dptr+len, dbuf.dsize-len);
2935
2936         SAFE_FREE(dbuf.dptr);
2937
2938         return True;    
2939 }
2940
2941 /****************************************************************************
2942  Initialize printer devmode & data with previously saved driver init values.
2943  When a printer is created using AddPrinter, the drivername bound to the
2944  printer is used to lookup previously saved driver initialization info, which
2945  is bound to the new printer.
2946 ****************************************************************************/
2947
2948 uint32 set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
2949 {
2950         uint32 result;
2951         
2952         switch (level)
2953         {
2954                 case 2:
2955                 {
2956                         result=set_driver_init_2(printer->info_2);
2957                         break;
2958                 }
2959                 default:
2960                         result=1;
2961                         break;
2962         }
2963         
2964         return result;
2965 }
2966
2967 /****************************************************************************
2968  Delete driver init data stored for a specified driver
2969 ****************************************************************************/
2970
2971 BOOL del_driver_init(char *drivername)
2972 {
2973         pstring key;
2974         TDB_DATA kbuf;
2975
2976         if (!drivername || !*drivername) {
2977                 DEBUG(3,("del_driver_init: No drivername specified!\n"));
2978                 return False;
2979         }
2980
2981         slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, drivername);
2982
2983         kbuf.dptr = key;
2984         kbuf.dsize = strlen(key)+1;
2985
2986         DEBUG(6,("del_driver_init: Removing driver init data for [%s]\n", drivername));
2987
2988         return (tdb_delete(tdb_drivers, kbuf) == 0);
2989 }
2990
2991 /****************************************************************************
2992  Pack up the DEVMODE and specifics for a printer into a 'driver init' entry 
2993  in the tdb. Note: this is different from the driver entry and the printer
2994  entry. There should be a single driver init entry for each driver regardless
2995  of whether it was installed from NT or 2K. Technically, they should be
2996  different, but they work out to the same struct.
2997 ****************************************************************************/
2998
2999 static uint32 update_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info)
3000 {
3001         pstring key;
3002         char *buf;
3003         int buflen, len, ret;
3004         TDB_DATA kbuf, dbuf;
3005
3006         buf = NULL;
3007         buflen = 0;
3008
3009  again: 
3010         len = 0;
3011         len += pack_devicemode(info->devmode, buf+len, buflen-len);
3012
3013         len += pack_specifics(info->specific, buf+len, buflen-len);
3014
3015         if (buflen != len) {
3016                 char *tb;
3017
3018                 tb = (char *)Realloc(buf, len);
3019                 if (!tb) {
3020                         DEBUG(0, ("update_driver_init_2: failed to enlarge buffer!\n"));
3021                         ret = -1;
3022                         goto done;
3023                 }
3024                 else buf = tb;
3025                 buflen = len;
3026                 goto again;
3027         }
3028
3029         slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info->drivername);
3030
3031         kbuf.dptr = key;
3032         kbuf.dsize = strlen(key)+1;
3033         dbuf.dptr = buf;
3034         dbuf.dsize = len;
3035
3036         ret = tdb_store(tdb_drivers, kbuf, dbuf, TDB_REPLACE);
3037
3038 done:
3039         if (ret == -1)
3040                 DEBUG(8, ("update_driver_init_2: error updating printer init to tdb on disk\n"));
3041
3042         SAFE_FREE(buf);
3043
3044         DEBUG(10,("update_driver_init_2: Saved printer [%s] init DEVMODE & specifics for driver [%s]\n",
3045                  info->sharename, info->drivername));
3046
3047         return ret;
3048 }
3049
3050 /****************************************************************************
3051  Update (i.e. save) the driver init info (DEVMODE and specifics) for a printer
3052 ****************************************************************************/
3053
3054 uint32 update_driver_init(NT_PRINTER_INFO_LEVEL printer, uint32 level)
3055 {
3056         uint32 result;
3057         
3058         dump_a_printer(printer, level); 
3059         
3060         switch (level)