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