a0dacc14c5785e7806e141b5a4ddf43f86284f13
[ira/wip.git] / source3 / printing / nt_printing.c
1 /*
2  *  Unix SMB/Netbios implementation.
3  *  Version 1.9.
4  *  RPC Pipe client / server routines
5  *  Copyright (C) Andrew Tridgell              1992-2000,
6  *  Copyright (C) Jean François Micouleau      1998-2000.
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22
23 #include "includes.h"
24
25 extern pstring global_myname;
26 extern DOM_SID global_sid_World;
27
28 static TDB_CONTEXT *tdb_forms; /* used for forms files */
29 static TDB_CONTEXT *tdb_drivers; /* used for driver files */
30 static TDB_CONTEXT *tdb_printers; /* used for printers files */
31
32 #define FORMS_PREFIX "FORMS/"
33 #define DRIVERS_PREFIX "DRIVERS/"
34 #define DRIVER_INIT_PREFIX "DRIVER_INIT/"
35 #define PRINTERS_PREFIX "PRINTERS/"
36 #define SECDESC_PREFIX "SECDESC/"
37  
38 #define NTDRIVERS_DATABASE_VERSION_1 1
39 #define NTDRIVERS_DATABASE_VERSION_2 2
40  
41 #define NTDRIVERS_DATABASE_VERSION NTDRIVERS_DATABASE_VERSION_2
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_2(void)
178 {
179         TDB_DATA kbuf, newkey, dbuf;
180  
181         DEBUG(0,("upgrade_to_version_2: upgrading print tdb's to version 2\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_2:moving form\n"));
190                         if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) {
191                                 DEBUG(0,("upgrade_to_version_2: 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_2: 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_2:moving printer\n"));
202                         if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
203                                 DEBUG(0,("upgrade_to_version_2: 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_2: 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_2:moving secdesc\n"));
214                         if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
215                                 DEBUG(0,("upgrade_to_version_2: 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_2: 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 BOOL nt_printing_init(void)
234 {
235         static pid_t local_pid;
236         char *vstring = "INFO/version";
237
238         if (tdb_drivers && tdb_printers && tdb_forms && local_pid == sys_getpid())
239                 return True;
240  
241         tdb_drivers = tdb_open_log(lock_path("ntdrivers.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
242         if (!tdb_drivers) {
243                 DEBUG(0,("nt_printing_init: Failed to open nt drivers database %s (%s)\n",
244                         lock_path("ntdrivers.tdb"), strerror(errno) ));
245                 return False;
246         }
247  
248         tdb_printers = tdb_open_log(lock_path("ntprinters.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
249         if (!tdb_printers) {
250                 DEBUG(0,("nt_printing_init: Failed to open nt printers database %s (%s)\n",
251                         lock_path("ntprinters.tdb"), strerror(errno) ));
252                 return False;
253         }
254  
255         tdb_forms = tdb_open_log(lock_path("ntforms.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
256         if (!tdb_forms) {
257                 DEBUG(0,("nt_printing_init: Failed to open nt forms database %s (%s)\n",
258                         lock_path("ntforms.tdb"), strerror(errno) ));
259                 return False;
260         }
261  
262         local_pid = sys_getpid();
263  
264         /* handle a Samba upgrade */
265         tdb_lock_bystring(tdb_drivers, vstring);
266         if (tdb_fetch_int(tdb_drivers, vstring) != NTDRIVERS_DATABASE_VERSION) {
267  
268                 if (tdb_fetch_int(tdb_drivers, vstring) == NTDRIVERS_DATABASE_VERSION_1) {
269                         if (!upgrade_to_version_2())
270                                 return False;
271                 } else
272                         tdb_traverse(tdb_drivers, tdb_traverse_delete_fn, NULL);
273  
274                 tdb_store_int(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION);
275         }
276         tdb_unlock_bystring(tdb_drivers, vstring);
277
278         return True;
279 }
280
281 /****************************************************************************
282  get builtin form struct list
283 ****************************************************************************/
284 int get_builtin_ntforms(nt_forms_struct **list)
285 {
286         *list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));
287         return sizeof(default_forms) / sizeof(default_forms[0]);
288 }
289
290 /****************************************************************************
291  get a builtin form struct
292 ****************************************************************************/
293
294 BOOL get_a_builtin_ntform(UNISTR2 *uni_formname,nt_forms_struct *form)
295 {
296         int i,count;
297         fstring form_name;
298         unistr2_to_ascii(form_name, uni_formname, sizeof(form_name)-1);
299         DEBUGADD(6,("Looking for builtin form %s \n", form_name));
300         count = sizeof(default_forms) / sizeof(default_forms[0]);
301         for (i=0;i<count;i++) {
302                 if (strequal(form_name,default_forms[i].name)) {
303                         DEBUGADD(6,("Found builtin form %s \n", form_name));
304                         memcpy(form,&default_forms[i],sizeof(*form));
305                         break;
306                 }
307         }
308
309         return (i !=count);
310 }
311
312 /****************************************************************************
313 get a form struct list
314 ****************************************************************************/
315 int get_ntforms(nt_forms_struct **list)
316 {
317         TDB_DATA kbuf, newkey, dbuf;
318         nt_forms_struct *tl;
319         nt_forms_struct form;
320         int ret;
321         int i;
322         int n = 0;
323
324         for (kbuf = tdb_firstkey(tdb_forms);
325              kbuf.dptr;
326              newkey = tdb_nextkey(tdb_forms, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
327                 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0) continue;
328                 
329                 dbuf = tdb_fetch(tdb_forms, kbuf);
330                 if (!dbuf.dptr) continue;
331
332                 fstrcpy(form.name, kbuf.dptr+strlen(FORMS_PREFIX));
333                 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddd",
334                                  &i, &form.flag, &form.width, &form.length, &form.left,
335                                  &form.top, &form.right, &form.bottom);
336                 SAFE_FREE(dbuf.dptr);
337                 if (ret != dbuf.dsize) continue;
338
339                 tl = Realloc(*list, sizeof(nt_forms_struct)*(n+1));
340                 if (!tl) {
341                         DEBUG(0,("get_ntforms: Realloc fail.\n"));
342                         return 0;
343                 }
344                 *list = tl;
345                 (*list)[n] = form;
346                 n++;
347         }
348         
349
350         return n;
351 }
352
353 /****************************************************************************
354 write a form struct list
355 ****************************************************************************/
356 int write_ntforms(nt_forms_struct **list, int number)
357 {
358         pstring buf, key;
359         int len;
360         TDB_DATA kbuf,dbuf;
361         int i;
362
363         for (i=0;i<number;i++) {
364                 /* save index, so list is rebuilt in correct order */
365                 len = tdb_pack(buf, sizeof(buf), "dddddddd",
366                                i, (*list)[i].flag, (*list)[i].width, (*list)[i].length,
367                                (*list)[i].left, (*list)[i].top, (*list)[i].right,
368                                (*list)[i].bottom);
369                 if (len > sizeof(buf)) break;
370                 slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[i].name);
371                 kbuf.dsize = strlen(key)+1;
372                 kbuf.dptr = key;
373                 dbuf.dsize = len;
374                 dbuf.dptr = buf;
375                 if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) break;
376        }
377
378        return i;
379 }
380
381 /****************************************************************************
382 add a form struct at the end of the list
383 ****************************************************************************/
384 BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
385 {
386         int n=0;
387         BOOL update;
388         fstring form_name;
389         nt_forms_struct *tl;
390
391         /*
392          * NT tries to add forms even when
393          * they are already in the base
394          * only update the values if already present
395          */
396
397         update=False;
398         
399         unistr2_to_ascii(form_name, &form->name, sizeof(form_name)-1);
400         for (n=0; n<*count; n++) {
401                 if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
402                         DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
403                         update=True;
404                         break;
405                 }
406         }
407
408         if (update==False) {
409                 if((tl=Realloc(*list, (n+1)*sizeof(nt_forms_struct))) == NULL) {
410                         DEBUG(0,("add_a_form: failed to enlarge forms list!\n"));
411                         return False;
412                 }
413                 *list = tl;
414                 unistr2_to_ascii((*list)[n].name, &form->name, sizeof((*list)[n].name)-1);
415                 (*count)++;
416         }
417         
418         (*list)[n].flag=form->flags;
419         (*list)[n].width=form->size_x;
420         (*list)[n].length=form->size_y;
421         (*list)[n].left=form->left;
422         (*list)[n].top=form->top;
423         (*list)[n].right=form->right;
424         (*list)[n].bottom=form->bottom;
425
426         return True;
427 }
428
429 /****************************************************************************
430  delete a named form struct
431 ****************************************************************************/
432 BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR *ret)
433 {
434         pstring key;
435         TDB_DATA kbuf;
436         int n=0;
437         fstring form_name;
438
439         *ret = WERR_OK;
440
441         unistr2_to_ascii(form_name, del_name, sizeof(form_name)-1);
442
443         for (n=0; n<*count; n++) {
444                 if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
445                         DEBUG(103, ("delete_a_form, [%s] in list\n", form_name));
446                         break;
447                 }
448         }
449
450         if (n == *count) {
451                 DEBUG(10,("delete_a_form, [%s] not found\n", form_name));
452                 *ret = WERR_INVALID_PARAM;
453                 return False;
454         }
455
456         slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[n].name);
457         kbuf.dsize = strlen(key)+1;
458         kbuf.dptr = key;
459         if (tdb_delete(tdb_forms, kbuf) != 0) {
460                 *ret = WERR_NOMEM;
461                 return False;
462         }
463
464         return True;
465 }
466
467 /****************************************************************************
468 update a form struct
469 ****************************************************************************/
470 void update_a_form(nt_forms_struct **list, const FORM *form, int count)
471 {
472         int n=0;
473         fstring form_name;
474         unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
475
476         DEBUG(106, ("[%s]\n", form_name));
477         for (n=0; n<count; n++)
478         {
479                 DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
480                 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
481                         break;
482         }
483
484         if (n==count) return;
485
486         (*list)[n].flag=form->flags;
487         (*list)[n].width=form->size_x;
488         (*list)[n].length=form->size_y;
489         (*list)[n].left=form->left;
490         (*list)[n].top=form->top;
491         (*list)[n].right=form->right;
492         (*list)[n].bottom=form->bottom;
493 }
494
495 /****************************************************************************
496 get the nt drivers list
497
498 traverse the database and look-up the matching names
499 ****************************************************************************/
500 int get_ntdrivers(fstring **list, char *architecture, uint32 version)
501 {
502         int total=0;
503         fstring short_archi;
504         fstring *fl;
505         pstring key;
506         TDB_DATA kbuf, newkey;
507
508         get_short_archi(short_archi, architecture);
509         slprintf(key, sizeof(key)-1, "%s%s/%d/", DRIVERS_PREFIX, short_archi, version);
510
511         for (kbuf = tdb_firstkey(tdb_drivers);
512              kbuf.dptr;
513              newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
514                 if (strncmp(kbuf.dptr, key, strlen(key)) != 0) continue;
515                 
516                 if((fl = Realloc(*list, sizeof(fstring)*(total+1))) == NULL) {
517                         DEBUG(0,("get_ntdrivers: failed to enlarge list!\n"));
518                         return -1;
519                 }
520                 else *list = fl;
521
522                 fstrcpy((*list)[total], kbuf.dptr+strlen(key));
523                 total++;
524         }
525
526         return(total);
527 }
528
529 /****************************************************************************
530 function to do the mapping between the long architecture name and
531 the short one.
532 ****************************************************************************/
533 BOOL get_short_archi(char *short_archi, char *long_archi)
534 {
535         struct table {
536                 char *long_archi;
537                 char *short_archi;
538         };
539         
540         struct table archi_table[]=
541         {
542                 {"Windows 4.0",          "WIN40"    },
543                 {"Windows NT x86",       "W32X86"   },
544                 {"Windows NT R4000",     "W32MIPS"  },
545                 {"Windows NT Alpha_AXP", "W32ALPHA" },
546                 {"Windows NT PowerPC",   "W32PPC"   },
547                 {NULL,                   ""         }
548         };
549         
550         int i=-1;
551
552         DEBUG(107,("Getting architecture dependant directory\n"));
553         do {
554                 i++;
555         } while ( (archi_table[i].long_archi!=NULL ) &&
556                   StrCaseCmp(long_archi, archi_table[i].long_archi) );
557
558         if (archi_table[i].long_archi==NULL) {
559                 DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
560                 return False;
561         }
562
563         StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
564
565         DEBUGADD(108,("index: [%d]\n", i));
566         DEBUGADD(108,("long architecture: [%s]\n", long_archi));
567         DEBUGADD(108,("short architecture: [%s]\n", short_archi));
568         
569         return True;
570 }
571
572 /****************************************************************************
573 Version information in Microsoft files is held in a VS_VERSION_INFO structure.
574 There are two case to be covered here: PE (Portable Executable) and NE (New
575 Executable) files. Both files support the same INFO structure, but PE files
576 store the signature in unicode, and NE files store it as !unicode.
577 ****************************************************************************/
578 static BOOL get_file_version(files_struct *fsp, char *fname,uint32 *major,
579                                                          uint32 *minor)
580 {
581         int     i;
582         char    *buf;
583         ssize_t byte_count;
584
585         if ((buf=malloc(PE_HEADER_SIZE)) == NULL) {
586                 DEBUG(0,("get_file_version: PE file [%s] PE Header malloc failed bytes = %d\n",
587                                 fname, PE_HEADER_SIZE));
588                 goto error_exit;
589         }
590
591         /* Note: DOS_HEADER_SIZE < malloc'ed PE_HEADER_SIZE */
592         if ((byte_count = vfs_read_data(fsp, buf, DOS_HEADER_SIZE)) < DOS_HEADER_SIZE) {
593                 DEBUG(3,("get_file_version: File [%s] DOS header too short, bytes read = %d\n",
594                                 fname, byte_count));
595                 goto no_version_info;
596         }
597
598         /* Is this really a DOS header? */
599         if (SVAL(buf,DOS_HEADER_MAGIC_OFFSET) != DOS_HEADER_MAGIC) {
600                 DEBUG(6,("get_file_version: File [%s] bad DOS magic = 0x%x\n",
601                                 fname, SVAL(buf,DOS_HEADER_MAGIC_OFFSET)));
602                 goto no_version_info;
603         }
604
605         /* Skip OEM header (if any) and the DOS stub to start of Windows header */
606         if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
607                 DEBUG(3,("get_file_version: File [%s] too short, errno = %d\n",
608                                 fname, errno));
609                 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
610                 goto no_version_info;
611         }
612
613         if ((byte_count = vfs_read_data(fsp, buf, PE_HEADER_SIZE)) < PE_HEADER_SIZE) {
614                 DEBUG(3,("get_file_version: File [%s] Windows header too short, bytes read = %d\n",
615                                 fname, byte_count));
616                 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
617                 goto no_version_info;
618         }
619
620         /* The header may be a PE (Portable Executable) or an NE (New Executable) */
621         if (IVAL(buf,PE_HEADER_SIGNATURE_OFFSET) == PE_HEADER_SIGNATURE) {
622                 int num_sections;
623                 int section_table_bytes;
624                 
625                 if (SVAL(buf,PE_HEADER_MACHINE_OFFSET) != PE_HEADER_MACHINE_I386) {
626                         DEBUG(3,("get_file_version: PE file [%s] wrong machine = 0x%x\n",
627                                         fname, SVAL(buf,PE_HEADER_MACHINE_OFFSET)));
628                         /* At this point, we assume the file is in error. It still could be somthing
629                          * else besides a PE file, but it unlikely at this point.
630                          */
631                         goto error_exit;
632                 }
633
634                 /* get the section table */
635                 num_sections        = SVAL(buf,PE_HEADER_NUMBER_OF_SECTIONS);
636                 section_table_bytes = num_sections * PE_HEADER_SECT_HEADER_SIZE;
637                 SAFE_FREE(buf);
638                 if ((buf=malloc(section_table_bytes)) == NULL) {
639                         DEBUG(0,("get_file_version: PE file [%s] section table malloc failed bytes = %d\n",
640                                         fname, section_table_bytes));
641                         goto error_exit;
642                 }
643
644                 if ((byte_count = vfs_read_data(fsp, buf, section_table_bytes)) < section_table_bytes) {
645                         DEBUG(3,("get_file_version: PE file [%s] Section header too short, bytes read = %d\n",
646                                         fname, byte_count));
647                         goto error_exit;
648                 }
649
650                 /* Iterate the section table looking for the resource section ".rsrc" */
651                 for (i = 0; i < num_sections; i++) {
652                         int sec_offset = i * PE_HEADER_SECT_HEADER_SIZE;
653
654                         if (strcmp(".rsrc", &buf[sec_offset+PE_HEADER_SECT_NAME_OFFSET]) == 0) {
655                                 int section_pos   = IVAL(buf,sec_offset+PE_HEADER_SECT_PTR_DATA_OFFSET);
656                                 int section_bytes = IVAL(buf,sec_offset+PE_HEADER_SECT_SIZE_DATA_OFFSET);
657
658                                 SAFE_FREE(buf);
659                                 if ((buf=malloc(section_bytes)) == NULL) {
660                                         DEBUG(0,("get_file_version: PE file [%s] version malloc failed bytes = %d\n",
661                                                         fname, section_bytes));
662                                         goto error_exit;
663                                 }
664
665                                 /* Seek to the start of the .rsrc section info */
666                                 if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, section_pos, SEEK_SET) == (SMB_OFF_T)-1) {
667                                         DEBUG(3,("get_file_version: PE file [%s] too short for section info, errno = %d\n",
668                                                         fname, errno));
669                                         goto error_exit;
670                                 }
671
672                                 if ((byte_count = vfs_read_data(fsp, buf, section_bytes)) < section_bytes) {
673                                         DEBUG(3,("get_file_version: PE file [%s] .rsrc section too short, bytes read = %d\n",
674                                                         fname, byte_count));
675                                         goto error_exit;
676                                 }
677
678                                 for (i=0; i<section_bytes-VS_VERSION_INFO_UNICODE_SIZE; i++) {
679                                         /* Scan for 1st 3 unicoded bytes followed by word aligned magic value */
680                                         if (buf[i] == 'V' && buf[i+1] == '\0' && buf[i+2] == 'S') {
681                                                 /* Align to next long address */
682                                                 int pos = (i + sizeof(VS_SIGNATURE)*2 + 3) & 0xfffffffc;
683
684                                                 if (IVAL(buf,pos) == VS_MAGIC_VALUE) {
685                                                         *major = IVAL(buf,pos+VS_MAJOR_OFFSET);
686                                                         *minor = IVAL(buf,pos+VS_MINOR_OFFSET);
687                                                         
688                                                         DEBUG(6,("get_file_version: PE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
689                                                                           fname, *major, *minor,
690                                                                           (*major>>16)&0xffff, *major&0xffff,
691                                                                           (*minor>>16)&0xffff, *minor&0xffff));
692                                                         SAFE_FREE(buf);
693                                                         return True;
694                                                 }
695                                         }
696                                 }
697                         }
698                 }
699
700                 /* Version info not found, fall back to origin date/time */
701                 DEBUG(10,("get_file_version: PE file [%s] has no version info\n", fname));
702                 SAFE_FREE(buf);
703                 return False;
704
705         } else if (SVAL(buf,NE_HEADER_SIGNATURE_OFFSET) == NE_HEADER_SIGNATURE) {
706                 if (CVAL(buf,NE_HEADER_TARGET_OS_OFFSET) != NE_HEADER_TARGOS_WIN ) {
707                         DEBUG(3,("get_file_version: NE file [%s] wrong target OS = 0x%x\n",
708                                         fname, CVAL(buf,NE_HEADER_TARGET_OS_OFFSET)));
709                         /* At this point, we assume the file is in error. It still could be somthing
710                          * else besides a NE file, but it unlikely at this point. */
711                         goto error_exit;
712                 }
713
714                 /* Allocate a bit more space to speed up things */
715                 SAFE_FREE(buf);
716                 if ((buf=malloc(VS_NE_BUF_SIZE)) == NULL) {
717                         DEBUG(0,("get_file_version: NE file [%s] malloc failed bytes  = %d\n",
718                                         fname, PE_HEADER_SIZE));
719                         goto error_exit;
720                 }
721
722                 /* This is a HACK! I got tired of trying to sort through the messy
723                  * 'NE' file format. If anyone wants to clean this up please have at
724                  * it, but this works. 'NE' files will eventually fade away. JRR */
725                 while((byte_count = vfs_read_data(fsp, buf, VS_NE_BUF_SIZE)) > 0) {
726                         /* Cover case that should not occur in a well formed 'NE' .dll file */
727                         if (byte_count-VS_VERSION_INFO_SIZE <= 0) break;
728
729                         for(i=0; i<byte_count; i++) {
730                                 /* Fast skip past data that can't possibly match */
731                                 if (buf[i] != 'V') continue;
732
733                                 /* Potential match data crosses buf boundry, move it to beginning
734                                  * of buf, and fill the buf with as much as it will hold. */
735                                 if (i>byte_count-VS_VERSION_INFO_SIZE) {
736                                         int bc;
737
738                                         memcpy(buf, &buf[i], byte_count-i);
739                                         if ((bc = vfs_read_data(fsp, &buf[byte_count-i], VS_NE_BUF_SIZE-
740                                                                    (byte_count-i))) < 0) {
741
742                                                 DEBUG(0,("get_file_version: NE file [%s] Read error, errno=%d\n",
743                                                                  fname, errno));
744                                                 goto error_exit;
745                                         }
746
747                                         byte_count = bc + (byte_count - i);
748                                         if (byte_count<VS_VERSION_INFO_SIZE) break;
749
750                                         i = 0;
751                                 }
752
753                                 /* Check that the full signature string and the magic number that
754                                  * follows exist (not a perfect solution, but the chances that this
755                                  * occurs in code is, well, remote. Yes I know I'm comparing the 'V'
756                                  * twice, as it is simpler to read the code. */
757                                 if (strcmp(&buf[i], VS_SIGNATURE) == 0) {
758                                         /* Compute skip alignment to next long address */
759                                         int skip = -(fsp->conn->vfs_ops.lseek(fsp, fsp->fd, 0, SEEK_CUR) - (byte_count - i) +
760                                                                  sizeof(VS_SIGNATURE)) & 3;
761                                         if (IVAL(buf,i+sizeof(VS_SIGNATURE)+skip) != 0xfeef04bd) continue;
762
763                                         *major = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MAJOR_OFFSET);
764                                         *minor = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MINOR_OFFSET);
765                                         DEBUG(6,("get_file_version: NE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
766                                                           fname, *major, *minor,
767                                                           (*major>>16)&0xffff, *major&0xffff,
768                                                           (*minor>>16)&0xffff, *minor&0xffff));
769                                         SAFE_FREE(buf);
770                                         return True;
771                                 }
772                         }
773                 }
774
775                 /* Version info not found, fall back to origin date/time */
776                 DEBUG(0,("get_file_version: NE file [%s] Version info not found\n", fname));
777                 SAFE_FREE(buf);
778                 return False;
779
780         } else
781                 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
782                 DEBUG(3,("get_file_version: File [%s] unknown file format, signature = 0x%x\n",
783                                 fname, IVAL(buf,PE_HEADER_SIGNATURE_OFFSET)));
784
785         no_version_info:
786                 SAFE_FREE(buf);
787                 return False;
788
789         error_exit:
790                 SAFE_FREE(buf);
791                 return -1;
792 }
793
794 /****************************************************************************
795 Drivers for Microsoft systems contain multiple files. Often, multiple drivers
796 share one or more files. During the MS installation process files are checked
797 to insure that only a newer version of a shared file is installed over an
798 older version. There are several possibilities for this comparison. If there
799 is no previous version, the new one is newer (obviously). If either file is
800 missing the version info structure, compare the creation date (on Unix use
801 the modification date). Otherwise chose the numerically larger version number.
802 ****************************************************************************/
803 static int file_version_is_newer(connection_struct *conn, fstring new_file,
804                                                                 fstring old_file)
805 {
806         BOOL   use_version = True;
807         pstring filepath;
808
809         uint32 new_major;
810         uint32 new_minor;
811         time_t new_create_time;
812
813         uint32 old_major;
814         uint32 old_minor;
815         time_t old_create_time;
816
817         int access_mode;
818         int action;
819         files_struct    *fsp = NULL;
820         SMB_STRUCT_STAT st;
821         SMB_STRUCT_STAT stat_buf;
822         BOOL bad_path;
823
824         ZERO_STRUCT(st);
825         ZERO_STRUCT(stat_buf);
826         new_create_time = (time_t)0;
827         old_create_time = (time_t)0;
828
829         /* Get file version info (if available) for previous file (if it exists) */
830         pstrcpy(filepath, old_file);
831
832         unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
833
834         fsp = open_file_shared(conn, filepath, &stat_buf,
835                                                    SET_OPEN_MODE(DOS_OPEN_RDONLY),
836                                                    (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
837                                                    0, 0, &access_mode, &action);
838         if (!fsp) {
839                 /* Old file not found, so by definition new file is in fact newer */
840                 DEBUG(10,("file_version_is_newer: Can't open old file [%s], errno = %d\n",
841                                 filepath, errno));
842                 return True;
843
844         } else {
845                 int ret = get_file_version(fsp, old_file, &old_major, &old_minor);
846                 if (ret == -1) goto error_exit;
847
848                 if (!ret) {
849                         DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
850                                          old_file));
851                         use_version = False;
852                         if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit;
853                         old_create_time = st.st_mtime;
854                         DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", old_create_time));
855                 }
856         }
857         close_file(fsp, True);
858
859         /* Get file version info (if available) for new file */
860         pstrcpy(filepath, new_file);
861         unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
862
863         fsp = open_file_shared(conn, filepath, &stat_buf,
864                                                    SET_OPEN_MODE(DOS_OPEN_RDONLY),
865                                                    (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
866                                                    0, 0, &access_mode, &action);
867         if (!fsp) {
868                 /* New file not found, this shouldn't occur if the caller did its job */
869                 DEBUG(3,("file_version_is_newer: Can't open new file [%s], errno = %d\n",
870                                 filepath, errno));
871                 goto error_exit;
872
873         } else {
874                 int ret = get_file_version(fsp, new_file, &new_major, &new_minor);
875                 if (ret == -1) goto error_exit;
876
877                 if (!ret) {
878                         DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
879                                          new_file));
880                         use_version = False;
881                         if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit;
882                         new_create_time = st.st_mtime;
883                         DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", new_create_time));
884                 }
885         }
886         close_file(fsp, True);
887
888         if (use_version) {
889                 /* Compare versions and choose the larger version number */
890                 if (new_major > old_major ||
891                         (new_major == old_major && new_minor > old_minor)) {
892                         
893                         DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
894                         return True;
895                 }
896                 else {
897                         DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
898                         return False;
899                 }
900
901         } else {
902                 /* Compare modification time/dates and choose the newest time/date */
903                 if (new_create_time > old_create_time) {
904                         DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
905                         return True;
906                 }
907                 else {
908                         DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
909                         return False;
910                 }
911         }
912
913         error_exit:
914                 if(fsp)
915                         close_file(fsp, True);
916                 return -1;
917 }
918
919 /****************************************************************************
920 Determine the correct cVersion associated with an architecture and driver
921 ****************************************************************************/
922 static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in,
923                                    struct current_user *user, WERROR *perr)
924 {
925         int               cversion;
926         int               access_mode;
927         int               action;
928         NTSTATUS          nt_status;
929         pstring           driverpath;
930         DATA_BLOB         null_pw;
931         files_struct      *fsp = NULL;
932         BOOL              bad_path;
933         SMB_STRUCT_STAT   st;
934         connection_struct *conn;
935
936         ZERO_STRUCT(st);
937
938         *perr = WERR_INVALID_PARAM;
939
940         /* If architecture is Windows 95/98/ME, the version is always 0. */
941         if (strcmp(architecture, "WIN40") == 0) {
942                 DEBUG(10,("get_correct_cversion: Driver is Win9x, cversion = 0\n"));
943                 *perr = WERR_OK;
944                 return 0;
945         }
946
947         /* connect to the print$ share under the same account as the user connected to the rpc pipe */  
948         /* Null password is ok - we are already an authenticated user... */
949         null_pw = data_blob(NULL, 0);
950
951         become_root();
952         conn = make_connection("print$", null_pw, "A:", user->vuid, &nt_status);
953         unbecome_root();
954
955         if (conn == NULL) {
956                 DEBUG(0,("get_correct_cversion: Unable to connect\n"));
957                 *perr = ntstatus_to_werror(nt_status);
958                 return -1;
959         }
960
961         /* We are temporarily becoming the connection user. */
962         if (!become_user(conn, conn->vuid)) {
963                 DEBUG(0,("get_correct_cversion: Can't become user!\n"));
964                 *perr = WERR_ACCESS_DENIED;
965                 return -1;
966         }
967
968         /* Open the driver file (Portable Executable format) and determine the
969          * deriver the cversion. */
970         slprintf(driverpath, sizeof(driverpath)-1, "%s/%s", architecture, driverpath_in);
971
972         unix_convert(driverpath,conn,NULL,&bad_path,&st);
973
974         fsp = open_file_shared(conn, driverpath, &st,
975                                                    SET_OPEN_MODE(DOS_OPEN_RDONLY),
976                                                    (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
977                                                    0, 0, &access_mode, &action);
978         if (!fsp) {
979                 DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
980                                 driverpath, errno));
981                 *perr = WERR_ACCESS_DENIED;
982                 goto error_exit;
983         }
984         else {
985                 uint32 major;
986                 uint32 minor;
987                 int    ret = get_file_version(fsp, driverpath, &major, &minor);
988                 if (ret == -1) goto error_exit;
989
990                 if (!ret) {
991                         DEBUG(6,("get_correct_cversion: Version info not found [%s]\n", driverpath));
992                         goto error_exit;
993                 }
994
995                 /*
996                  * This is a Microsoft'ism. See references in MSDN to VER_FILEVERSION
997                  * for more details. Version in this case is not just the version of the 
998                  * file, but the version in the sense of kernal mode (2) vs. user mode
999                  * (3) drivers. Other bits of the version fields are the version info. 
1000                  * JRR 010716
1001                 */
1002                 cversion = major & 0x0000ffff;
1003                 switch (cversion) {
1004                         case 2: /* WinNT drivers */
1005                         case 3: /* Win2K drivers */
1006                                 break;
1007                         
1008                         default:
1009                                 DEBUG(6,("get_correct_cversion: cversion invalid [%s]  cversion = %d\n", 
1010                                         driverpath, cversion));
1011                                 goto error_exit;
1012                 }
1013
1014                 DEBUG(10,("get_correct_cversion: Version info found [%s]  major = 0x%x  minor = 0x%x\n",
1015                                   driverpath, major, minor));
1016         }
1017
1018         DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
1019                   driverpath, cversion));
1020
1021         close_file(fsp, True);
1022         close_cnum(conn, user->vuid);
1023         unbecome_user();
1024         *perr = WERR_OK;
1025         return cversion;
1026
1027   error_exit:
1028
1029         if(fsp)
1030                 close_file(fsp, True);
1031         
1032         close_cnum(conn, user->vuid);
1033         unbecome_user();
1034         return -1;
1035 }
1036
1037 /****************************************************************************
1038 ****************************************************************************/
1039 static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver,
1040                                              struct current_user *user)
1041 {
1042         fstring architecture;
1043         fstring new_name;
1044         char *p;
1045         int i;
1046         WERROR err;
1047
1048         /* clean up the driver name.
1049          * we can get .\driver.dll
1050          * or worse c:\windows\system\driver.dll !
1051          */
1052         /* using an intermediate string to not have overlaping memcpy()'s */
1053         if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
1054                 fstrcpy(new_name, p+1);
1055                 fstrcpy(driver->driverpath, new_name);
1056         }
1057
1058         if ((p = strrchr(driver->datafile,'\\')) != NULL) {
1059                 fstrcpy(new_name, p+1);
1060                 fstrcpy(driver->datafile, new_name);
1061         }
1062
1063         if ((p = strrchr(driver->configfile,'\\')) != NULL) {
1064                 fstrcpy(new_name, p+1);
1065                 fstrcpy(driver->configfile, new_name);
1066         }
1067
1068         if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
1069                 fstrcpy(new_name, p+1);
1070                 fstrcpy(driver->helpfile, new_name);
1071         }
1072
1073         if (driver->dependentfiles) {
1074                 for (i=0; *driver->dependentfiles[i]; i++) {
1075                         if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
1076                                 fstrcpy(new_name, p+1);
1077                                 fstrcpy(driver->dependentfiles[i], new_name);
1078                         }
1079                 }
1080         }
1081
1082         get_short_archi(architecture, driver->environment);
1083         
1084         /* jfm:7/16/2000 the client always sends the cversion=0.
1085          * The server should check which version the driver is by reading
1086          * the PE header of driver->driverpath.
1087          *
1088          * For Windows 95/98 the version is 0 (so the value sent is correct)
1089          * For Windows NT (the architecture doesn't matter)
1090          *      NT 3.1: cversion=0
1091          *      NT 3.5/3.51: cversion=1
1092          *      NT 4: cversion=2
1093          *      NT2K: cversion=3
1094          */
1095         if ((driver->cversion = get_correct_cversion( architecture,
1096                                                       driver->driverpath, user, &err)) == -1)
1097                 return err;
1098
1099         return WERR_OK;
1100 }
1101         
1102 /****************************************************************************
1103 ****************************************************************************/
1104 static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver,
1105                                              struct current_user *user)
1106 {
1107         fstring architecture;
1108         fstring new_name;
1109         char *p;
1110         int i;
1111         WERROR err;
1112
1113         /* clean up the driver name.
1114          * we can get .\driver.dll
1115          * or worse c:\windows\system\driver.dll !
1116          */
1117         /* using an intermediate string to not have overlaping memcpy()'s */
1118         if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
1119                 fstrcpy(new_name, p+1);
1120                 fstrcpy(driver->driverpath, new_name);
1121         }
1122
1123         if ((p = strrchr(driver->datafile,'\\')) != NULL) {
1124                 fstrcpy(new_name, p+1);
1125                 fstrcpy(driver->datafile, new_name);
1126         }
1127
1128         if ((p = strrchr(driver->configfile,'\\')) != NULL) {
1129                 fstrcpy(new_name, p+1);
1130                 fstrcpy(driver->configfile, new_name);
1131         }
1132
1133         if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
1134                 fstrcpy(new_name, p+1);
1135                 fstrcpy(driver->helpfile, new_name);
1136         }
1137
1138         if (driver->dependentfiles) {
1139                 for (i=0; *driver->dependentfiles[i]; i++) {
1140                         if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
1141                                 fstrcpy(new_name, p+1);
1142                                 fstrcpy(driver->dependentfiles[i], new_name);
1143                         }
1144                 }
1145         }
1146
1147         get_short_archi(architecture, driver->environment);
1148
1149         /* jfm:7/16/2000 the client always sends the cversion=0.
1150          * The server should check which version the driver is by reading
1151          * the PE header of driver->driverpath.
1152          *
1153          * For Windows 95/98 the version is 0 (so the value sent is correct)
1154          * For Windows NT (the architecture doesn't matter)
1155          *      NT 3.1: cversion=0
1156          *      NT 3.5/3.51: cversion=1
1157          *      NT 4: cversion=2
1158          *      NT2K: cversion=3
1159          */
1160         if ((driver->version = get_correct_cversion(architecture,
1161                                                     driver->driverpath, user, &err)) == -1)
1162                 return err;
1163
1164         return WERR_OK;
1165 }
1166
1167 /****************************************************************************
1168 ****************************************************************************/
1169 WERROR clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
1170                                                           uint32 level, struct current_user *user)
1171 {
1172         switch (level) {
1173                 case 3:
1174                 {
1175                         NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
1176                         driver=driver_abstract.info_3;
1177                         return clean_up_driver_struct_level_3(driver, user);
1178                 }
1179                 case 6:
1180                 {
1181                         NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver;
1182                         driver=driver_abstract.info_6;
1183                         return clean_up_driver_struct_level_6(driver, user);
1184                 }
1185                 default:
1186                         return WERR_INVALID_PARAM;
1187         }
1188 }
1189
1190 /****************************************************************************
1191  This function sucks and should be replaced. JRA.
1192 ****************************************************************************/
1193
1194 static void convert_level_6_to_level3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dst, NT_PRINTER_DRIVER_INFO_LEVEL_6 *src)
1195 {
1196     dst->cversion  = src->version;
1197
1198     fstrcpy( dst->name, src->name);
1199     fstrcpy( dst->environment, src->environment);
1200     fstrcpy( dst->driverpath, src->driverpath);
1201     fstrcpy( dst->datafile, src->datafile);
1202     fstrcpy( dst->configfile, src->configfile);
1203     fstrcpy( dst->helpfile, src->helpfile);
1204     fstrcpy( dst->monitorname, src->monitorname);
1205     fstrcpy( dst->defaultdatatype, src->defaultdatatype);
1206     dst->dependentfiles = src->dependentfiles;
1207 }
1208
1209 #if 0 /* Debugging function */
1210
1211 static char* ffmt(unsigned char *c){
1212         int i;
1213         static char ffmt_str[17];
1214
1215         for (i=0; i<16; i++) {
1216                 if ((c[i] < ' ') || (c[i] > '~'))
1217                         ffmt_str[i]='.';
1218                 else
1219                         ffmt_str[i]=c[i];
1220         }
1221     ffmt_str[16]='\0';
1222         return ffmt_str;
1223 }
1224
1225 #endif
1226
1227 /****************************************************************************
1228 ****************************************************************************/
1229 BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level, 
1230                                   struct current_user *user, WERROR *perr)
1231 {
1232         NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
1233         NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver;
1234         fstring architecture;
1235         pstring new_dir;
1236         pstring old_name;
1237         pstring new_name;
1238         DATA_BLOB null_pw;
1239         connection_struct *conn;
1240         NTSTATUS nt_status;
1241         int ver = 0;
1242         int i;
1243
1244         *perr = WERR_OK;
1245
1246         if (level==3)
1247                 driver=driver_abstract.info_3;
1248         else if (level==6) {
1249                 convert_level_6_to_level3(&converted_driver, driver_abstract.info_6);
1250                 driver = &converted_driver;
1251         } else {
1252                 DEBUG(0,("move_driver_to_download_area: Unknown info level (%u)\n", (unsigned int)level ));
1253                 return False;
1254         }
1255
1256         get_short_archi(architecture, driver->environment);
1257
1258         /* connect to the print$ share under the same account as the user connected to the rpc pipe */  
1259         /* Null password is ok - we are already an authenticated user... */
1260         null_pw = data_blob(NULL, 0);
1261         conn = make_connection("print$", null_pw, "A:", user->vuid, &nt_status);
1262
1263         if (conn == NULL) {
1264                 DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
1265                 *perr = ntstatus_to_werror(nt_status);
1266                 return False;
1267         }
1268
1269         /*
1270          * Save who we are - we are temporarily becoming the connection user.
1271          */
1272
1273         push_sec_ctx();
1274
1275         if (!become_user(conn, conn->vuid)) {
1276                 DEBUG(0,("move_driver_to_download_area: Can't become user!\n"));
1277                 pop_sec_ctx();
1278                 return False;
1279         }
1280
1281         /*
1282          * make the directories version and version\driver_name
1283          * under the architecture directory.
1284          */
1285         DEBUG(5,("Creating first directory\n"));
1286         slprintf(new_dir, sizeof(new_dir)-1, "%s/%d", architecture, driver->cversion);
1287         mkdir_internal(conn, new_dir);
1288
1289         /* For each driver file, archi\filexxx.yyy, if there is a duplicate file
1290          * listed for this driver which has already been moved, skip it (note:
1291          * drivers may list the same file name several times. Then check if the
1292          * file already exists in archi\cversion\, if so, check that the version
1293          * info (or time stamps if version info is unavailable) is newer (or the
1294          * date is later). If it is, move it to archi\cversion\filexxx.yyy.
1295          * Otherwise, delete the file.
1296          *
1297          * If a file is not moved to archi\cversion\ because of an error, all the
1298          * rest of the 'unmoved' driver files are removed from archi\. If one or
1299          * more of the driver's files was already moved to archi\cversion\, it
1300          * potentially leaves the driver in a partially updated state. Version
1301          * trauma will most likely occur if an client attempts to use any printer
1302          * bound to the driver. Perhaps a rewrite to make sure the moves can be
1303          * done is appropriate... later JRR
1304          */
1305
1306         DEBUG(5,("Moving files now !\n"));
1307
1308         if (driver->driverpath && strlen(driver->driverpath)) {
1309                 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->driverpath);      
1310                 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->driverpath);   
1311                 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1312                         NTSTATUS status;
1313                         status = rename_internals(conn, new_name, old_name, True);
1314                         if (!NT_STATUS_IS_OK(status)) {
1315                                 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1316                                                 new_name, old_name));
1317                                 *perr = ntstatus_to_werror(status);
1318                                 unlink_internals(conn, 0, new_name);
1319                                 ver = -1;
1320                         }
1321                 }
1322                 else
1323                         unlink_internals(conn, 0, new_name);
1324         }
1325
1326         if (driver->datafile && strlen(driver->datafile)) {
1327                 if (!strequal(driver->datafile, driver->driverpath)) {
1328                         slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->datafile);        
1329                         slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->datafile);     
1330                         if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1331                                 NTSTATUS status;
1332                                 status = rename_internals(conn, new_name, old_name, True);
1333                                 if (!NT_STATUS_IS_OK(status)) {
1334                                         DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1335                                                         new_name, old_name));
1336                                         *perr = ntstatus_to_werror(status);
1337                                         unlink_internals(conn, 0, new_name);
1338                                         ver = -1;
1339                                 }
1340                         }
1341                         else
1342                                 unlink_internals(conn, 0, new_name);
1343                 }
1344         }
1345
1346         if (driver->configfile && strlen(driver->configfile)) {
1347                 if (!strequal(driver->configfile, driver->driverpath) &&
1348                         !strequal(driver->configfile, driver->datafile)) {
1349                         slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->configfile);      
1350                         slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->configfile);   
1351                         if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1352                                 NTSTATUS status;
1353                                 status = rename_internals(conn, new_name, old_name, True);
1354                                 if (!NT_STATUS_IS_OK(status)) {
1355                                         DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1356                                                         new_name, old_name));
1357                                         *perr = ntstatus_to_werror(status);
1358                                         unlink_internals(conn, 0, new_name);
1359                                         ver = -1;
1360                                 }
1361                         }
1362                         else
1363                                 unlink_internals(conn, 0, new_name);
1364                 }
1365         }
1366
1367         if (driver->helpfile && strlen(driver->helpfile)) {
1368                 if (!strequal(driver->helpfile, driver->driverpath) &&
1369                         !strequal(driver->helpfile, driver->datafile) &&
1370                         !strequal(driver->helpfile, driver->configfile)) {
1371                         slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->helpfile);        
1372                         slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->helpfile);     
1373                         if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1374                                 NTSTATUS status;
1375                                 status = rename_internals(conn, new_name, old_name, True);
1376                                 if (!NT_STATUS_IS_OK(status)) {
1377                                         DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1378                                                         new_name, old_name));
1379                                         *perr = ntstatus_to_werror(status);
1380                                         unlink_internals(conn, 0, new_name);
1381                                         ver = -1;
1382                                 }
1383                         }
1384                         else
1385                                 unlink_internals(conn, 0, new_name);
1386                 }
1387         }
1388
1389         if (driver->dependentfiles) {
1390                 for (i=0; *driver->dependentfiles[i]; i++) {
1391                         if (!strequal(driver->dependentfiles[i], driver->driverpath) &&
1392                                 !strequal(driver->dependentfiles[i], driver->datafile) &&
1393                                 !strequal(driver->dependentfiles[i], driver->configfile) &&
1394                                 !strequal(driver->dependentfiles[i], driver->helpfile)) {
1395                                 int j;
1396                                 for (j=0; j < i; j++) {
1397                                         if (strequal(driver->dependentfiles[i], driver->dependentfiles[j])) {
1398                                                 goto NextDriver;
1399                                         }
1400                                 }
1401
1402                                 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->dependentfiles[i]);       
1403                                 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->dependentfiles[i]);    
1404                                 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1405                                         NTSTATUS status;
1406                                         status = rename_internals(conn, new_name, old_name, True);
1407                                         if (!NT_STATUS_IS_OK(status)) {
1408                                                 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1409                                                                 new_name, old_name));
1410                                                 *perr = ntstatus_to_werror(status);
1411                                                 unlink_internals(conn, 0, new_name);
1412                                                 ver = -1;
1413                                         }
1414                                 }
1415                                 else
1416                                         unlink_internals(conn, 0, new_name);
1417                         }
1418                 NextDriver: ;
1419                 }
1420         }
1421
1422         close_cnum(conn, user->vuid);
1423         pop_sec_ctx();
1424
1425         return ver == -1 ? False : True;
1426 }
1427
1428 /****************************************************************************
1429 ****************************************************************************/
1430 static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
1431 {
1432         int len, buflen;
1433         fstring architecture;
1434         pstring directory;
1435         pstring temp_name;
1436         pstring key;
1437         char *buf;
1438         int i, ret;
1439         TDB_DATA kbuf, dbuf;
1440
1441         get_short_archi(architecture, driver->environment);
1442
1443         /* The names are relative. We store them in the form: \print$\arch\version\driver.xxx
1444          * \\server is added in the rpc server layer.
1445          * It does make sense to NOT store the server's name in the printer TDB.
1446          */
1447
1448         slprintf(directory, sizeof(directory)-1, "\\print$\\%s\\%d\\", architecture, driver->cversion);
1449
1450     /* .inf files do not always list a file for each of the four standard files. 
1451      * Don't prepend a path to a null filename, or client claims:
1452      *   "The server on which the printer resides does not have a suitable 
1453      *   <printer driver name> printer driver installed. Click OK if you 
1454      *   wish to install the driver on your local machine."
1455      */
1456         if (strlen(driver->driverpath)) {
1457         fstrcpy(temp_name, driver->driverpath);
1458         slprintf(driver->driverpath, sizeof(driver->driverpath)-1, "%s%s", directory, temp_name);
1459     }
1460
1461         if (strlen(driver->datafile)) {
1462         fstrcpy(temp_name, driver->datafile);
1463         slprintf(driver->datafile, sizeof(driver->datafile)-1, "%s%s", directory, temp_name);
1464     }
1465
1466         if (strlen(driver->configfile)) {
1467         fstrcpy(temp_name, driver->configfile);
1468         slprintf(driver->configfile, sizeof(driver->configfile)-1, "%s%s", directory, temp_name);
1469     }
1470
1471         if (strlen(driver->helpfile)) {
1472         fstrcpy(temp_name, driver->helpfile);
1473         slprintf(driver->helpfile, sizeof(driver->helpfile)-1, "%s%s", directory, temp_name);
1474     }
1475
1476         if (driver->dependentfiles) {
1477                 for (i=0; *driver->dependentfiles[i]; i++) {
1478             fstrcpy(temp_name, driver->dependentfiles[i]);
1479             slprintf(driver->dependentfiles[i], sizeof(driver->dependentfiles[i])-1, "%s%s", directory, temp_name);
1480                 }
1481         }
1482
1483         slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, driver->cversion, driver->name);
1484
1485         DEBUG(5,("add_a_printer_driver_3: Adding driver with key %s\n", key ));
1486
1487         buf = NULL;
1488         len = buflen = 0;
1489
1490  again:
1491         len = 0;
1492         len += tdb_pack(buf+len, buflen-len, "dffffffff",
1493                         driver->cversion,
1494                         driver->name,
1495                         driver->environment,
1496                         driver->driverpath,
1497                         driver->datafile,
1498                         driver->configfile,
1499                         driver->helpfile,
1500                         driver->monitorname,
1501                         driver->defaultdatatype);
1502
1503         if (driver->dependentfiles) {
1504                 for (i=0; *driver->dependentfiles[i]; i++) {
1505                         len += tdb_pack(buf+len, buflen-len, "f",
1506                                         driver->dependentfiles[i]);
1507                 }
1508         }
1509
1510         if (len != buflen) {
1511                 char *tb;
1512                 
1513                 tb = (char *)Realloc(buf, len);
1514                 if (!tb) {
1515                         DEBUG(0,("add_a_printer_driver_3: failed to enlarge buffer\n!"));
1516                         ret = -1;
1517                         goto done;
1518                 }
1519                 else buf = tb;
1520                 buflen = len;
1521                 goto again;
1522         }
1523
1524
1525         kbuf.dptr = key;
1526         kbuf.dsize = strlen(key)+1;
1527         dbuf.dptr = buf;
1528         dbuf.dsize = len;
1529         
1530         ret = tdb_store(tdb_drivers, kbuf, dbuf, TDB_REPLACE);
1531
1532 done:
1533         if (ret)
1534                 DEBUG(0,("add_a_printer_driver_3: Adding driver with key %s failed.\n", key ));
1535
1536         SAFE_FREE(buf);
1537         return ret;
1538 }
1539
1540 /****************************************************************************
1541 ****************************************************************************/
1542 static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
1543 {
1544         NT_PRINTER_DRIVER_INFO_LEVEL_3 info3;
1545
1546         ZERO_STRUCT(info3);
1547         info3.cversion = driver->version;
1548         fstrcpy(info3.name,driver->name);
1549         fstrcpy(info3.environment,driver->environment);
1550         fstrcpy(info3.driverpath,driver->driverpath);
1551         fstrcpy(info3.datafile,driver->datafile);
1552         fstrcpy(info3.configfile,driver->configfile);
1553         fstrcpy(info3.helpfile,driver->helpfile);
1554         fstrcpy(info3.monitorname,driver->monitorname);
1555         fstrcpy(info3.defaultdatatype,driver->defaultdatatype);
1556         info3.dependentfiles = driver->dependentfiles;
1557
1558         return add_a_printer_driver_3(&info3);
1559 }
1560
1561
1562 /****************************************************************************
1563 ****************************************************************************/
1564 static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
1565 {
1566         NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
1567
1568         ZERO_STRUCT(info);
1569
1570         fstrcpy(info.name, in_prt);
1571         fstrcpy(info.defaultdatatype, "RAW");
1572         
1573         fstrcpy(info.driverpath, "");
1574         fstrcpy(info.datafile, "");
1575         fstrcpy(info.configfile, "");
1576         fstrcpy(info.helpfile, "");
1577
1578         if ((info.dependentfiles=(fstring *)malloc(2*sizeof(fstring))) == NULL)
1579                 return WERR_NOMEM;
1580
1581         memset(info.dependentfiles, '\0', 2*sizeof(fstring));
1582         fstrcpy(info.dependentfiles[0], "");
1583
1584         *info_ptr = memdup(&info, sizeof(info));
1585         
1586         return WERR_OK;
1587 }
1588
1589 /****************************************************************************
1590 ****************************************************************************/
1591 static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch, uint32 version)
1592 {
1593         NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
1594         TDB_DATA kbuf, dbuf;
1595         fstring architecture;
1596         int len = 0;
1597         int i;
1598         pstring key;
1599
1600         ZERO_STRUCT(driver);
1601
1602         get_short_archi(architecture, in_arch);
1603
1604         DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, in_prt));
1605
1606         slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, in_prt);
1607
1608         kbuf.dptr = key;
1609         kbuf.dsize = strlen(key)+1;
1610         
1611         dbuf = tdb_fetch(tdb_drivers, kbuf);
1612 #if 0
1613         if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
1614 #else
1615         if (!dbuf.dptr) return WERR_ACCESS_DENIED;
1616 #endif
1617         len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff",
1618                           &driver.cversion,
1619                           driver.name,
1620                           driver.environment,
1621                           driver.driverpath,
1622                           driver.datafile,
1623                           driver.configfile,
1624                           driver.helpfile,
1625                           driver.monitorname,
1626                           driver.defaultdatatype);
1627
1628         i=0;
1629         while (len < dbuf.dsize) {
1630                 fstring *tddfs;
1631         
1632                 tddfs = (fstring *)Realloc(driver.dependentfiles,
1633                                                          sizeof(fstring)*(i+2));
1634                 if (tddfs == NULL) {
1635                         DEBUG(0,("get_a_printer_driver_3: failed to enlarge buffer!\n"));
1636                         break;
1637                 }
1638                 else driver.dependentfiles = tddfs;
1639
1640                 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f",
1641                                   &driver.dependentfiles[i]);
1642                 i++;
1643         }
1644         if (driver.dependentfiles != NULL)
1645                 fstrcpy(driver.dependentfiles[i], "");
1646
1647         SAFE_FREE(dbuf.dptr);
1648
1649         if (len != dbuf.dsize) {
1650                 SAFE_FREE(driver.dependentfiles);
1651
1652                 return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
1653         }
1654
1655         *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
1656
1657         return WERR_OK;
1658 }
1659
1660 /****************************************************************************
1661 ****************************************************************************/
1662 uint32 get_a_printer_driver_9x_compatible(pstring line, fstring model)
1663 {
1664         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1665         TDB_DATA kbuf;
1666         pstring key;
1667         int i;
1668         line[0] = '\0';
1669
1670         slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, "WIN40", 0, model);
1671         DEBUG(10,("driver key: [%s]\n", key));
1672         
1673         kbuf.dptr = key;
1674         kbuf.dsize = strlen(key)+1;
1675         if (!tdb_exists(tdb_drivers, kbuf)) return False;
1676
1677         ZERO_STRUCT(info3);
1678         get_a_printer_driver_3(&info3, model, "Windows 4.0", 0);
1679         
1680     DEBUGADD(10,("info3->name            [%s]\n", info3->name));
1681     DEBUGADD(10,("info3->datafile        [%s]\n", info3->datafile));
1682     DEBUGADD(10,("info3->helpfile        [%s]\n", info3->helpfile));
1683     DEBUGADD(10,("info3->monitorname     [%s]\n", info3->monitorname));
1684     DEBUGADD(10,("info3->defaultdatatype [%s]\n", info3->defaultdatatype));
1685         for (i=0; info3->dependentfiles && *info3->dependentfiles[i]; i++) {
1686     DEBUGADD(10,("info3->dependentfiles  [%s]\n", info3->dependentfiles[i]));
1687     }
1688     DEBUGADD(10,("info3->environment     [%s]\n", info3->environment));
1689     DEBUGADD(10,("info3->driverpath      [%s]\n", info3->driverpath));
1690     DEBUGADD(10,("info3->configfile      [%s]\n", info3->configfile));
1691
1692         /*pstrcat(line, info3->name);             pstrcat(line, ":");*/
1693         trim_string(info3->configfile, "\\print$\\WIN40\\0\\", 0);
1694         pstrcat(line, info3->configfile);
1695     pstrcat(line, ":");
1696         trim_string(info3->datafile, "\\print$\\WIN40\\0\\", 0);
1697         pstrcat(line, info3->datafile);
1698     pstrcat(line, ":");
1699         trim_string(info3->helpfile, "\\print$\\WIN40\\0\\", 0);
1700         pstrcat(line, info3->helpfile);
1701     pstrcat(line, ":");
1702         trim_string(info3->monitorname, "\\print$\\WIN40\\0\\", 0);
1703         pstrcat(line, info3->monitorname);
1704     pstrcat(line, ":");
1705         pstrcat(line, "RAW");                /*info3->defaultdatatype);*/
1706     pstrcat(line, ":");
1707
1708         for (i=0; info3->dependentfiles &&
1709                  *info3->dependentfiles[i]; i++) {
1710                 if (i) pstrcat(line, ",");               /* don't end in a "," */
1711                 trim_string(info3->dependentfiles[i], "\\print$\\WIN40\\0\\", 0);
1712                 pstrcat(line, info3->dependentfiles[i]);
1713         }
1714         
1715         SAFE_FREE(info3);
1716
1717         return True;    
1718 }
1719
1720 /****************************************************************************
1721 debugging function, dump at level 6 the struct in the logs
1722 ****************************************************************************/
1723 static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1724 {
1725         uint32 result;
1726         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1727         int i;
1728         
1729         DEBUG(106,("Dumping printer driver at level [%d]\n", level));
1730         
1731         switch (level)
1732         {
1733                 case 3:
1734                 {
1735                         if (driver.info_3 == NULL)
1736                                 result=5;
1737                         else {
1738                                 info3=driver.info_3;
1739                         
1740                                 DEBUGADD(106,("version:[%d]\n",         info3->cversion));
1741                                 DEBUGADD(106,("name:[%s]\n",            info3->name));
1742                                 DEBUGADD(106,("environment:[%s]\n",     info3->environment));
1743                                 DEBUGADD(106,("driverpath:[%s]\n",      info3->driverpath));
1744                                 DEBUGADD(106,("datafile:[%s]\n",        info3->datafile));
1745                                 DEBUGADD(106,("configfile:[%s]\n",      info3->configfile));
1746                                 DEBUGADD(106,("helpfile:[%s]\n",        info3->helpfile));
1747                                 DEBUGADD(106,("monitorname:[%s]\n",     info3->monitorname));
1748                                 DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
1749                                 
1750                                 for (i=0; info3->dependentfiles &&
1751                                           *info3->dependentfiles[i]; i++) {
1752                                         DEBUGADD(106,("dependentfile:[%s]\n",
1753                                                       info3->dependentfiles[i]));
1754                                 }
1755                                 result=0;
1756                         }
1757                         break;
1758                 }
1759                 default:
1760                         DEBUGADD(1,("Level not implemented\n"));
1761                         result=1;
1762                         break;
1763         }
1764         
1765         return result;
1766 }
1767
1768 /****************************************************************************
1769 ****************************************************************************/
1770 static int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
1771 {
1772         int len = 0;
1773
1774         len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
1775
1776         if (!nt_devmode) return len;
1777
1778         len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
1779                         nt_devmode->devicename,
1780                         nt_devmode->formname,
1781
1782                         nt_devmode->specversion,
1783                         nt_devmode->driverversion,
1784                         nt_devmode->size,
1785                         nt_devmode->driverextra,
1786                         nt_devmode->orientation,
1787                         nt_devmode->papersize,
1788                         nt_devmode->paperlength,
1789                         nt_devmode->paperwidth,
1790                         nt_devmode->scale,
1791                         nt_devmode->copies,
1792                         nt_devmode->defaultsource,
1793                         nt_devmode->printquality,
1794                         nt_devmode->color,
1795                         nt_devmode->duplex,
1796                         nt_devmode->yresolution,
1797                         nt_devmode->ttoption,
1798                         nt_devmode->collate,
1799                         nt_devmode->logpixels,
1800                         
1801                         nt_devmode->fields,
1802                         nt_devmode->bitsperpel,
1803                         nt_devmode->pelswidth,
1804                         nt_devmode->pelsheight,
1805                         nt_devmode->displayflags,
1806                         nt_devmode->displayfrequency,
1807                         nt_devmode->icmmethod,
1808                         nt_devmode->icmintent,
1809                         nt_devmode->mediatype,
1810                         nt_devmode->dithertype,
1811                         nt_devmode->reserved1,
1812                         nt_devmode->reserved2,
1813                         nt_devmode->panningwidth,
1814                         nt_devmode->panningheight,
1815                         nt_devmode->private);
1816
1817         
1818         if (nt_devmode->private) {
1819                 len += tdb_pack(buf+len, buflen-len, "B",
1820                                 nt_devmode->driverextra,
1821                                 nt_devmode->private);
1822         }
1823
1824         DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname));
1825
1826         return len;
1827 }
1828
1829 /****************************************************************************
1830 ****************************************************************************/
1831 static int pack_specifics(NT_PRINTER_PARAM *param, char *buf, int buflen)
1832 {
1833         int len = 0;
1834
1835         while (param != NULL) {
1836                 len += tdb_pack(buf+len, buflen-len, "pfdB",
1837                                 param,
1838                                 param->value,
1839                                 param->type,
1840                                 param->data_len,
1841                                 param->data);
1842                 param=param->next;      
1843         }
1844
1845         len += tdb_pack(buf+len, buflen-len, "p", param);
1846
1847         return len;
1848 }
1849
1850
1851 /****************************************************************************
1852 delete a printer - this just deletes the printer info file, any open
1853 handles are not affected
1854 ****************************************************************************/
1855 uint32 del_a_printer(char *sharename)
1856 {
1857         pstring key;
1858         TDB_DATA kbuf;
1859
1860         slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
1861
1862         kbuf.dptr=key;
1863         kbuf.dsize=strlen(key)+1;
1864
1865         tdb_delete(tdb_printers, kbuf);
1866         return 0;
1867 }
1868
1869 /* FIXME!!!  Reorder so this forward declaration is not necessary --jerry */
1870 static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **, fstring);
1871 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **);
1872 /****************************************************************************
1873 ****************************************************************************/
1874 static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
1875 {
1876         pstring key;
1877         char *buf;
1878         int buflen, len;
1879         WERROR ret;
1880         TDB_DATA kbuf, dbuf;
1881         
1882         /*
1883          * in addprinter: no servername and the printer is the name
1884          * in setprinter: servername is \\server
1885          *                and printer is \\server\\printer
1886          *
1887          * Samba manages only local printers.
1888          * we currently don't support things like path=\\other_server\printer
1889          */
1890
1891         if (info->servername[0]!='\0') {
1892                 trim_string(info->printername, info->servername, NULL);
1893                 trim_string(info->printername, "\\", NULL);
1894                 info->servername[0]='\0';
1895         }
1896
1897         /*
1898          * JFM: one day I'll forget.
1899          * below that's info->portname because that's the SAMBA sharename
1900          * and I made NT 'thinks' it's the portname
1901          * the info->sharename is the thing you can name when you add a printer
1902          * that's the short-name when you create shared printer for 95/98
1903          * So I've made a limitation in SAMBA: you can only have 1 printer model
1904          * behind a SAMBA share.
1905          */
1906
1907         buf = NULL;
1908         buflen = 0;
1909
1910  again: 
1911         len = 0;
1912         len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffPfffff",
1913                         info->attributes,
1914                         info->priority,
1915                         info->default_priority,
1916                         info->starttime,
1917                         info->untiltime,
1918                         info->status,
1919                         info->cjobs,
1920                         info->averageppm,
1921                         info->changeid,
1922                         info->c_setprinter,
1923                         info->setuptime,
1924                         info->servername,
1925                         info->printername,
1926                         info->sharename,
1927                         info->portname,
1928                         info->drivername,
1929                         info->comment,
1930                         info->location,
1931                         info->sepfile,
1932                         info->printprocessor,
1933                         info->datatype,
1934                         info->parameters);
1935
1936         len += pack_devicemode(info->devmode, buf+len, buflen-len);
1937         
1938         len += pack_specifics(info->specific, buf+len, buflen-len);
1939
1940         if (buflen != len) {
1941                 char *tb;
1942                 
1943                 tb = (char *)Realloc(buf, len);
1944                 if (!tb) {
1945                         DEBUG(0,("update_a_printer_2: failed to enlarge buffer!\n"));
1946                         ret = WERR_NOMEM;
1947                         goto done;
1948                 }
1949                 else buf = tb;
1950                 buflen = len;
1951                 goto again;
1952         }
1953         
1954
1955         slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, info->sharename);
1956
1957         kbuf.dptr = key;
1958         kbuf.dsize = strlen(key)+1;
1959         dbuf.dptr = buf;
1960         dbuf.dsize = len;
1961
1962         ret = (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) == 0? WERR_OK : WERR_NOMEM);
1963
1964 done:
1965         if (!W_ERROR_IS_OK(ret))
1966                 DEBUG(8, ("error updating printer to tdb on disk\n"));
1967
1968         SAFE_FREE(buf);
1969
1970         DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n",
1971                  info->sharename, info->drivername, info->portname, len));
1972
1973         return ret;
1974 }
1975
1976
1977 /****************************************************************************
1978 ****************************************************************************/
1979 void add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM **param)
1980 {
1981         NT_PRINTER_PARAM *current;
1982         
1983         DEBUG(108,("add_a_specific_param\n"));  
1984
1985         (*param)->next=NULL;
1986         
1987         if (info_2->specific == NULL)
1988         {
1989                 info_2->specific=*param;
1990         }
1991         else
1992         {
1993                 current=info_2->specific;               
1994                 while (current->next != NULL) {
1995                         current=current->next;
1996                 }               
1997                 current->next=*param;
1998         }
1999
2000         *param = NULL;
2001 }
2002
2003 /****************************************************************************
2004 ****************************************************************************/
2005 BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
2006 {
2007         NT_PRINTER_PARAM *current;
2008         NT_PRINTER_PARAM *previous;
2009         
2010         current=info_2->specific;
2011         previous=current;
2012         
2013         if (current==NULL) return (False);
2014         
2015         if ( !strcmp(current->value, param->value) &&
2016             (strlen(current->value)==strlen(param->value)) ) {
2017                 DEBUG(109,("deleting first value\n"));
2018                 info_2->specific=current->next;
2019                 SAFE_FREE(current->data);
2020                 SAFE_FREE(current);
2021                 DEBUG(109,("deleted first value\n"));
2022                 return (True);
2023         }
2024
2025         current=previous->next;
2026                 
2027         while ( current!=NULL ) {
2028                 if (!strcmp(current->value, param->value) &&
2029                     strlen(current->value)==strlen(param->value) ) {
2030                         DEBUG(109,("deleting current value\n"));
2031                         previous->next=current->next;
2032                         SAFE_FREE(current->data);
2033                         SAFE_FREE(current);
2034                         DEBUG(109,("deleted current value\n"));
2035                         return(True);
2036                 }
2037                 
2038                 previous=previous->next;
2039                 current=current->next;
2040         }
2041         return (False);
2042 }
2043
2044 /****************************************************************************
2045  Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
2046 ****************************************************************************/
2047 void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr)
2048 {
2049         NT_PRINTER_PARAM *param = *param_ptr;
2050
2051         if(param == NULL)
2052                 return;
2053
2054         DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param->value));
2055
2056         SAFE_FREE(param->data);
2057         SAFE_FREE(*param_ptr);
2058 }
2059
2060 /****************************************************************************
2061  Malloc and return an NT devicemode.
2062 ****************************************************************************/
2063
2064 NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
2065 {
2066 /*
2067  * should I init this ones ???
2068         nt_devmode->devicename
2069 */
2070
2071         char adevice[32];
2072         NT_DEVICEMODE *nt_devmode = (NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE));
2073
2074         if (nt_devmode == NULL) {
2075                 DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
2076                 return NULL;
2077         }
2078
2079         ZERO_STRUCTP(nt_devmode);
2080
2081         safe_strcpy(adevice, default_devicename, sizeof(adevice));
2082         fstrcpy(nt_devmode->devicename, adevice);       
2083         
2084         fstrcpy(nt_devmode->formname, "Letter");
2085
2086         nt_devmode->specversion      = 0x0401;
2087         nt_devmode->driverversion    = 0x0400;
2088         nt_devmode->size             = 0x00DC;
2089         nt_devmode->driverextra      = 0x0000;
2090         nt_devmode->fields           = FORMNAME | TTOPTION | PRINTQUALITY |
2091                                        DEFAULTSOURCE | COPIES | SCALE |
2092                                        PAPERSIZE | ORIENTATION;
2093         nt_devmode->orientation      = 1;
2094         nt_devmode->papersize        = PAPER_LETTER;
2095         nt_devmode->paperlength      = 0;
2096         nt_devmode->paperwidth       = 0;
2097         nt_devmode->scale            = 0x64;
2098         nt_devmode->copies           = 1;
2099         nt_devmode->defaultsource    = BIN_FORMSOURCE;
2100         nt_devmode->printquality     = RES_HIGH;           /* 0x0258 */
2101         nt_devmode->color            = COLOR_MONOCHROME;
2102         nt_devmode->duplex           = DUP_SIMPLEX;
2103         nt_devmode->yresolution      = 0;
2104         nt_devmode->ttoption         = TT_SUBDEV;
2105         nt_devmode->collate          = COLLATE_FALSE;
2106         nt_devmode->icmmethod        = 0;
2107         nt_devmode->icmintent        = 0;
2108         nt_devmode->mediatype        = 0;
2109         nt_devmode->dithertype       = 0;
2110
2111         /* non utilisés par un driver d'imprimante */
2112         nt_devmode->logpixels        = 0;
2113         nt_devmode->bitsperpel       = 0;
2114         nt_devmode->pelswidth        = 0;
2115         nt_devmode->pelsheight       = 0;
2116         nt_devmode->displayflags     = 0;
2117         nt_devmode->displayfrequency = 0;
2118         nt_devmode->reserved1        = 0;
2119         nt_devmode->reserved2        = 0;
2120         nt_devmode->panningwidth     = 0;
2121         nt_devmode->panningheight    = 0;
2122         
2123         nt_devmode->private = NULL;
2124         return nt_devmode;
2125 }
2126
2127 /****************************************************************************
2128  Deepcopy an NT devicemode.
2129 ****************************************************************************/
2130
2131 NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
2132 {
2133         NT_DEVICEMODE *new_nt_devicemode = NULL;
2134
2135         if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
2136                 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
2137                 return NULL;
2138         }
2139
2140         new_nt_devicemode->private = NULL;
2141         if (nt_devicemode->private != NULL) {
2142                 if ((new_nt_devicemode->private = memdup(nt_devicemode->private, nt_devicemode->driverextra)) == NULL) {
2143                         SAFE_FREE(new_nt_devicemode);
2144                         DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
2145                         return NULL;
2146         }
2147         }
2148
2149         return new_nt_devicemode;
2150 }
2151
2152 /****************************************************************************
2153  Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
2154 ****************************************************************************/
2155
2156 void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
2157 {
2158         NT_DEVICEMODE *nt_devmode = *devmode_ptr;
2159
2160         if(nt_devmode == NULL)
2161                 return;
2162
2163         DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
2164
2165         SAFE_FREE(nt_devmode->private);
2166         SAFE_FREE(*devmode_ptr);
2167 }
2168
2169 /****************************************************************************
2170  Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
2171 ****************************************************************************/
2172 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
2173 {
2174         NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
2175         NT_PRINTER_PARAM *param_ptr;
2176
2177         if(info == NULL)
2178                 return;
2179
2180         DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
2181
2182         free_nt_devicemode(&info->devmode);
2183
2184         for(param_ptr = info->specific; param_ptr; ) {
2185                 NT_PRINTER_PARAM *tofree = param_ptr;
2186
2187                 param_ptr = param_ptr->next;
2188                 free_nt_printer_param(&tofree);
2189         }
2190
2191         SAFE_FREE(*info_ptr);
2192 }
2193
2194
2195 /****************************************************************************
2196 ****************************************************************************/
2197 static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
2198 {
2199         int len = 0;
2200         int extra_len = 0;
2201         NT_DEVICEMODE devmode;
2202
2203         ZERO_STRUCT(devmode);
2204
2205         len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
2206
2207         if (!*nt_devmode) return len;
2208
2209         len += tdb_unpack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
2210                           devmode.devicename,
2211                           devmode.formname,
2212
2213                           &devmode.specversion,
2214                           &devmode.driverversion,
2215                           &devmode.size,
2216                           &devmode.driverextra,
2217                           &devmode.orientation,
2218                           &devmode.papersize,
2219                           &devmode.paperlength,
2220                           &devmode.paperwidth,
2221                           &devmode.scale,
2222                           &devmode.copies,
2223                           &devmode.defaultsource,
2224                           &devmode.printquality,
2225                           &devmode.color,
2226                           &devmode.duplex,
2227                           &devmode.yresolution,
2228                           &devmode.ttoption,
2229                           &devmode.collate,
2230                           &devmode.logpixels,
2231                         
2232                           &devmode.fields,
2233                           &devmode.bitsperpel,
2234                           &devmode.pelswidth,
2235                           &devmode.pelsheight,
2236                           &devmode.displayflags,
2237                           &devmode.displayfrequency,
2238                           &devmode.icmmethod,
2239                           &devmode.icmintent,
2240                           &devmode.mediatype,
2241                           &devmode.dithertype,
2242                           &devmode.reserved1,
2243                           &devmode.reserved2,
2244                           &devmode.panningwidth,
2245                           &devmode.panningheight,
2246                           &devmode.private);
2247         
2248         if (devmode.private) {
2249                 /* the len in tdb_unpack is an int value and
2250                  * devmode.driverextra is only a short
2251                  */
2252                 len += tdb_unpack(buf+len, buflen-len, "B", &extra_len, &devmode.private);
2253                 devmode.driverextra=(uint16)extra_len;
2254                 
2255                 /* check to catch an invalid TDB entry so we don't segfault */
2256                 if (devmode.driverextra == 0) {
2257                         devmode.private = NULL;
2258                 }
2259         }
2260
2261         *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
2262
2263         DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode.devicename, devmode.formname));
2264         if (devmode.private)
2265                 DEBUG(8,("with a private section of %d bytes\n", devmode.driverextra));
2266
2267         return len;
2268 }
2269
2270 /****************************************************************************
2271 ****************************************************************************/
2272 static int unpack_specifics(NT_PRINTER_PARAM **list, char *buf, int buflen)
2273 {
2274         int len = 0;
2275         NT_PRINTER_PARAM param, *p;
2276
2277         *list = NULL;
2278
2279         while (1) {
2280                 len += tdb_unpack(buf+len, buflen-len, "p", &p);
2281                 if (!p) break;
2282
2283                 len += tdb_unpack(buf+len, buflen-len, "fdB",
2284                                   param.value,
2285                                   &param.type,
2286                                   &param.data_len,
2287                                   &param.data);
2288                 param.next = *list;
2289                 *list = memdup(&param, sizeof(param));
2290
2291                 DEBUG(8,("specific: [%s], len: %d\n", param.value, param.data_len));
2292         }
2293
2294         return len;
2295 }
2296
2297 static void map_to_os2_driver(fstring drivername)
2298 {
2299         static BOOL initialised=False;
2300         static fstring last_from,last_to;
2301         char *mapfile = lp_os2_driver_map();
2302         char **lines = NULL;
2303         int numlines = 0;
2304         int i;
2305
2306         if (!strlen(drivername))
2307                 return;
2308
2309         if (!*mapfile)
2310                 return;
2311
2312         if (!initialised) {
2313                 *last_from = *last_to = 0;
2314                 initialised = True;
2315         }
2316
2317         if (strequal(drivername,last_from)) {
2318                 DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",drivername,last_to));
2319                 fstrcpy(drivername,last_to);
2320                 return;
2321         }
2322
2323         lines = file_lines_load(mapfile, &numlines);
2324         if (numlines == 0) {
2325                 DEBUG(0,("No entries in OS/2 driver map %s\n",mapfile));
2326                 return;
2327         }
2328
2329         DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile));
2330
2331         for( i = 0; i < numlines; i++) {
2332                 char *nt_name = lines[i];
2333                 char *os2_name = strchr(nt_name,'=');
2334
2335                 if (!os2_name)
2336                         continue;
2337
2338                 *os2_name++ = 0;
2339
2340                 while (isspace(*nt_name))
2341                         nt_name++;
2342
2343                 if (!*nt_name || strchr("#;",*nt_name))
2344                         continue;
2345
2346                 {
2347                         int l = strlen(nt_name);
2348                         while (l && isspace(nt_name[l-1])) {
2349                                 nt_name[l-1] = 0;
2350                                 l--;
2351                         }
2352                 }
2353
2354                 while (isspace(*os2_name))
2355                         os2_name++;
2356
2357                 {
2358                         int l = strlen(os2_name);
2359                         while (l && isspace(os2_name[l-1])) {
2360                                 os2_name[l-1] = 0;
2361                                 l--;
2362                         }
2363                 }
2364
2365                 if (strequal(nt_name,drivername)) {
2366                         DEBUG(3,("Mapped windows driver %s to os2 driver%s\n",drivername,os2_name));
2367                         fstrcpy(last_from,drivername);
2368                         fstrcpy(last_to,os2_name);
2369                         fstrcpy(drivername,os2_name);
2370                         file_lines_free(lines);
2371                         return;
2372                 }
2373         }
2374
2375         file_lines_free(lines);
2376 }
2377
2378 /****************************************************************************
2379 get a default printer info 2 struct
2380 ****************************************************************************/
2381 static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
2382 {
2383         extern pstring global_myname;
2384         int snum;
2385         NT_PRINTER_INFO_LEVEL_2 info;
2386
2387         ZERO_STRUCT(info);
2388
2389         snum = lp_servicenumber(sharename);
2390
2391         slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", global_myname);
2392         slprintf(info.printername, sizeof(info.printername)-1, "\\\\%s\\%s", 
2393                  global_myname, sharename);
2394         fstrcpy(info.sharename, sharename);
2395         fstrcpy(info.portname, SAMBA_PRINTER_PORT_NAME);
2396         fstrcpy(info.drivername, lp_printerdriver(snum));
2397
2398         /* by setting the driver name to an empty string, a local NT admin
2399            can now run the **local** APW to install a local printer driver
2400            for a Samba shared printer in 2.2.  Without this, drivers **must** be 
2401            installed on the Samba server for NT clients --jerry */
2402 #if 0   /* JERRY --do not uncomment-- */
2403         if (!*info.drivername)
2404                 fstrcpy(info.drivername, "NO DRIVER AVAILABLE FOR THIS PRINTER");
2405 #endif
2406
2407
2408         DEBUG(10,("get_a_printer_2_default: driver name set to [%s]\n", info.drivername));
2409
2410         pstrcpy(info.comment, "");
2411         fstrcpy(info.printprocessor, "winprint");
2412         fstrcpy(info.datatype, "RAW");
2413
2414         info.attributes = PRINTER_ATTRIBUTE_SHARED   \
2415                          | PRINTER_ATTRIBUTE_LOCAL  \
2416                          | PRINTER_ATTRIBUTE_RAW_ONLY \
2417                          | PRINTER_ATTRIBUTE_QUEUED ;            /* attributes */
2418
2419         info.starttime = 0; /* Minutes since 12:00am GMT */
2420         info.untiltime = 0; /* Minutes since 12:00am GMT */
2421         info.priority = 1;
2422         info.default_priority = 1;
2423         info.setuptime = (uint32)time(NULL) - 86400;    /* minus 1 day */
2424
2425         /*
2426          * I changed this as I think it is better to have a generic
2427          * DEVMODE than to crash Win2k explorer.exe   --jerry
2428          * See the HP Deskjet 990c Win2k drivers for an example.
2429          */
2430
2431 #if 0 /* JRA - NO NOT CHANGE ! */
2432         info.devmode = NULL;
2433 #else
2434         /*
2435          * We should not return a default devicemode, as this causes
2436          * Win2K to not send the correct one on PCL drivers. It needs to
2437          * see a null devicemode so it can then overwrite the devicemode
2438          * on OpenPrinterEx. Yes this *is* insane :-). JRA.
2439          */
2440         if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
2441                 goto fail;
2442 #endif
2443
2444         /* This will get the current RPC talloc context, but we should be
2445            passing this as a parameter... fixme... JRA ! */
2446
2447         if (!nt_printing_getsec(get_talloc_ctx(), sharename, &info.secdesc_buf))
2448                 goto fail;
2449
2450         *info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
2451         if (! *info_ptr) {
2452                 DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
2453                 goto fail;
2454         }
2455
2456         return WERR_OK;
2457
2458   fail:
2459
2460         if (info.devmode)
2461                 free_nt_devicemode(&info.devmode);
2462         return WERR_ACCESS_DENIED;
2463 }
2464
2465 /****************************************************************************
2466 ****************************************************************************/
2467 static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
2468 {
2469         pstring key;
2470         NT_PRINTER_INFO_LEVEL_2 info;
2471         int             len = 0;
2472         TDB_DATA kbuf, dbuf;
2473         fstring printername;
2474                 
2475         ZERO_STRUCT(info);
2476
2477         slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
2478
2479         kbuf.dptr = key;
2480         kbuf.dsize = strlen(key)+1;
2481
2482         dbuf = tdb_fetch(tdb_printers, kbuf);
2483         if (!dbuf.dptr)
2484                 return get_a_printer_2_default(info_ptr, sharename);
2485
2486         len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff",
2487                         &info.attributes,
2488                         &info.priority,
2489                         &info.default_priority,
2490                         &info.starttime,
2491                         &info.untiltime,
2492                         &info.status,
2493                         &info.cjobs,
2494                         &info.averageppm,
2495                         &info.changeid,
2496                         &info.c_setprinter,
2497                         &info.setuptime,
2498                         info.servername,
2499                         info.printername,
2500                         info.sharename,
2501                         info.portname,
2502                         info.drivername,
2503                         info.comment,
2504                         info.location,
2505                         info.sepfile,
2506                         info.printprocessor,
2507                         info.datatype,
2508                         info.parameters);
2509
2510         /* Samba has to have shared raw drivers. */
2511         info.attributes |= (PRINTER_ATTRIBUTE_SHARED|PRINTER_ATTRIBUTE_RAW_ONLY);
2512
2513         /* Restore the stripped strings. */
2514         slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", global_myname);
2515         slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", global_myname,
2516                         info.printername);
2517         fstrcpy(info.printername, printername);
2518
2519         len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
2520 #if 1
2521         /*
2522          * Some client drivers freak out if there is a NULL devmode
2523          * (probably the driver is not checking before accessing 
2524          * the devmode pointer)   --jerry
2525          */
2526         if (!info.devmode)
2527         {
2528                 DEBUG(8,("get_a_printer_2: Constructing a default device mode for [%s]\n",
2529                         printername));
2530                 info.devmode = construct_nt_devicemode(printername);
2531         }
2532 #endif
2533         len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
2534
2535         /* This will get the current RPC talloc context, but we should be
2536        passing this as a parameter... fixme... JRA ! */
2537
2538         nt_printing_getsec(get_talloc_ctx(), sharename, &info.secdesc_buf);
2539
2540         /* Fix for OS/2 drivers. */
2541
2542         if (get_remote_arch() == RA_OS2)
2543                 map_to_os2_driver(info.drivername);
2544
2545         SAFE_FREE(dbuf.dptr);
2546         *info_ptr=memdup(&info, sizeof(info));
2547
2548         DEBUG(9,("Unpacked printer [%s] name [%s] running driver [%s]\n",
2549                  sharename, info.printername, info.drivername));
2550
2551         return WERR_OK; 
2552 }
2553
2554 /****************************************************************************
2555 debugging function, dump at level 6 the struct in the logs
2556 ****************************************************************************/
2557 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2558 {
2559         uint32 result;
2560         NT_PRINTER_INFO_LEVEL_2 *info2;
2561         
2562         DEBUG(106,("Dumping printer at level [%d]\n", level));
2563         
2564         switch (level)
2565         {
2566                 case 2:
2567                 {
2568                         if (printer.info_2 == NULL)
2569                                 result=5;
2570                         else
2571                         {
2572                                 info2=printer.info_2;
2573                         
2574                                 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
2575                                 DEBUGADD(106,("priority:[%d]\n", info2->priority));
2576                                 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
2577                                 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
2578                                 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
2579                                 DEBUGADD(106,("status:[%d]\n", info2->status));
2580                                 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
2581                                 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
2582                                 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
2583                                 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
2584                                 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
2585
2586                                 DEBUGADD(106,("servername:[%s]\n", info2->servername));
2587                                 DEBUGADD(106,("printername:[%s]\n", info2->printername));
2588                                 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
2589                                 DEBUGADD(106,("portname:[%s]\n", info2->portname));
2590                                 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
2591                                 DEBUGADD(106,("comment:[%s]\n", info2->comment));
2592                                 DEBUGADD(106,("location:[%s]\n", info2->location));
2593                                 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
2594                                 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
2595                                 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
2596                                 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
2597                                 result=0;
2598                         }
2599                         break;
2600                 }
2601                 default:
2602                         DEBUGADD(1,("Level not implemented\n"));
2603                         result=1;
2604                         break;
2605         }
2606         
2607         return result;
2608 }
2609
2610 /****************************************************************************
2611  Get the parameters we can substitute in an NT print job.
2612 ****************************************************************************/
2613
2614 void get_printer_subst_params(int snum, fstring *printername, fstring *sharename, fstring *portname)
2615 {
2616         NT_PRINTER_INFO_LEVEL *printer = NULL;
2617         
2618         **printername = **sharename = **portname = '\0';
2619
2620         if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
2621                 return;
2622
2623         fstrcpy(*printername, printer->info_2->printername);
2624         fstrcpy(*sharename, printer->info_2->sharename);
2625         fstrcpy(*portname, printer->info_2->portname);
2626
2627         free_a_printer(&printer, 2);
2628 }
2629
2630 /*
2631  * The function below are the high level ones.
2632  * only those ones must be called from the spoolss code.
2633  * JFM.
2634  */
2635
2636 /****************************************************************************
2637  Modify a printer. This is called from SETPRINTERDATA/DELETEPRINTERDATA.
2638 ****************************************************************************/
2639
2640 WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2641 {
2642         WERROR result;
2643         
2644         dump_a_printer(printer, level); 
2645         
2646         switch (level)
2647         {
2648                 case 2:
2649                 {
2650                         /*
2651                          * Update the changestamp.  Emperical tests show that the
2652                          * ChangeID is always updated,but c_setprinter is only 
2653                          * incremented on a SetPrinter() call.
2654                          */
2655
2656                         time_t time_unix = time(NULL);
2657
2658                         /* ChangeID **must** be increasing over the lifetime
2659                            of client's spoolss service in order for the 
2660                            client's cache to show updates */
2661
2662                         printer.info_2->changeid = time_unix * 100;
2663
2664                         /*
2665                          * Because one day someone will ask:
2666                          * NT->NT       An admin connection to a remote
2667                          *              printer show changes imeediately in
2668                          *              the properities dialog
2669                          *      
2670                          *              A non-admin connection will only show the
2671                          *              changes after viewing the properites page
2672                          *              2 times.  Seems to be related to a
2673                          *              race condition in the client between the spooler
2674                          *              updating the local cache and the Explorer.exe GUI
2675                          *              actually displaying the properties.
2676                          *
2677                          *              This is fixed in Win2k.  admin/non-admin
2678                          *              connections both display changes immediately.
2679                          *
2680                          * 14/12/01     --jerry
2681                          */
2682
2683                         result=update_a_printer_2(printer.info_2);
2684                         break;
2685                 }
2686                 default:
2687                         result=WERR_UNKNOWN_LEVEL;
2688                         break;
2689         }
2690         
2691         return result;
2692 }
2693
2694 /****************************************************************************
2695  Add a printer. This is called from ADDPRINTER(EX) and also SETPRINTER.
2696  We split this out from mod_a_printer as it updates the id's and timestamps.
2697 ****************************************************************************/
2698
2699 WERROR add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2700 {
2701         WERROR result;
2702         
2703         dump_a_printer(printer, level); 
2704         
2705         switch (level)
2706         {
2707                 case 2:
2708                 {
2709                         /*
2710                          * Update the changestamp.  See comments in mod_a_printer()
2711                          * --jerry
2712                          */
2713
2714                         time_t time_unix = time(NULL);
2715
2716                         printer.info_2->changeid = time_unix * 100;
2717                         printer.info_2->c_setprinter++;
2718
2719                         result=update_a_printer_2(printer.info_2);
2720                         break;
2721                 }
2722                 default:
2723                         result=WERR_UNKNOWN_LEVEL;
2724                         break;
2725         }
2726         
2727         return result;
2728 }
2729
2730 /****************************************************************************
2731  Initialize printer devmode & data with previously saved driver init values.
2732 ****************************************************************************/
2733 static uint32 set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr)
2734 {
2735         int                     len = 0;
2736         pstring                 key;
2737         TDB_DATA                kbuf, dbuf;
2738         NT_PRINTER_PARAM        *current;
2739         NT_PRINTER_INFO_LEVEL_2 info;
2740
2741         ZERO_STRUCT(info);
2742
2743         slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info_ptr->drivername);
2744
2745         kbuf.dptr = key;
2746         kbuf.dsize = strlen(key)+1;
2747
2748         dbuf = tdb_fetch(tdb_drivers, kbuf);
2749         if (!dbuf.dptr)
2750                 return False;
2751
2752         /*
2753          * Get the saved DEVMODE..
2754          */
2755         len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
2756
2757         /*
2758          * The saved DEVMODE contains the devicename from the printer used during
2759          * the initialization save. Change it to reflect the new printer.
2760          */
2761         ZERO_STRUCT(info.devmode->devicename);
2762         fstrcpy(info.devmode->devicename, info_ptr->printername);
2763
2764         /* 
2765          *      Bind the saved DEVMODE to the new the printer.
2766          */
2767         free_nt_devicemode(&info_ptr->devmode);
2768         info_ptr->devmode = info.devmode;
2769
2770         DEBUG(10,("set_driver_init_2: Set printer [%s] init DEVMODE for driver [%s]\n",
2771                         info_ptr->printername, info_ptr->drivername));
2772
2773         /* 
2774          * There should not be any printer data 'specifics' already set during the
2775          * add printer operation, if there are delete them. 
2776          */
2777         while ( (current=info_ptr->specific) != NULL ) {
2778                 info_ptr->specific=current->next;
2779                 SAFE_FREE(current->data);
2780                 SAFE_FREE(current);
2781         }
2782
2783         /* 
2784          * Add the printer data 'specifics' to the new printer
2785          */
2786         len += unpack_specifics(&info_ptr->specific,dbuf.dptr+len, dbuf.dsize-len);
2787
2788         SAFE_FREE(dbuf.dptr);
2789
2790         return True;    
2791 }
2792
2793 /****************************************************************************
2794  Initialize printer devmode & data with previously saved driver init values.
2795  When a printer is created using AddPrinter, the drivername bound to the
2796  printer is used to lookup previously saved driver initialization info, which
2797  is bound to the new printer.
2798 ****************************************************************************/
2799
2800 uint32 set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
2801 {
2802         uint32 result;
2803         
2804         switch (level)
2805         {
2806                 case 2:
2807                 {
2808                         result=set_driver_init_2(printer->info_2);
2809                         break;
2810                 }
2811                 default:
2812                         result=1;
2813                         break;
2814         }
2815         
2816         return result;
2817 }
2818
2819 /****************************************************************************
2820  Pack up the DEVMODE and specifics for a printer into a 'driver init' entry 
2821  in the tdb. Note: this is different from the driver entry and the printer
2822  entry. There should be a single driver init entry for each driver regardless
2823  of whether it was installed from NT or 2K. Technically, they should be
2824  different, but they work out to the same struct.
2825 ****************************************************************************/
2826 static uint32 update_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info)
2827 {
2828         pstring key;
2829         char *buf;
2830         int buflen, len, ret;
2831         TDB_DATA kbuf, dbuf;
2832
2833         buf = NULL;
2834         buflen = 0;
2835
2836  again: 
2837         len = 0;
2838         len += pack_devicemode(info->devmode, buf+len, buflen-len);
2839
2840         len += pack_specifics(info->specific, buf+len, buflen-len);
2841
2842         if (buflen != len) {
2843                 char *tb;
2844                 
2845                 tb = (char *)Realloc(buf, len);
2846                 if (!tb) {
2847                         DEBUG(0, ("update_driver_init_2: failed to enlarge buffer!\n"));
2848                         ret = -1;
2849                         goto done;
2850                 }
2851                 else buf = tb;
2852                 buflen = len;
2853                 goto again;
2854         }
2855
2856         slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info->drivername);
2857
2858         kbuf.dptr = key;
2859         kbuf.dsize = strlen(key)+1;
2860         dbuf.dptr = buf;
2861         dbuf.dsize = len;
2862
2863         ret = tdb_store(tdb_drivers, kbuf, dbuf, TDB_REPLACE);
2864
2865 done:
2866         if (ret == -1)
2867                 DEBUG(8, ("update_driver_init_2: error updating printer init to tdb on disk\n"));
2868
2869         SAFE_FREE(buf);
2870
2871         DEBUG(10,("update_driver_init_2: Saved printer [%s] init DEVMODE & specifics for driver [%s]\n",
2872                  info->sharename, info->drivername));
2873
2874         return ret;
2875 }
2876
2877 /****************************************************************************
2878  Update (i.e. save) the driver init info (DEVMODE and specifics) for a printer
2879 ****************************************************************************/
2880
2881 static uint32 update_driver_init(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2882 {
2883         uint32 result;
2884         
2885         dump_a_printer(printer, level); 
2886         
2887         switch (level)
2888         {
2889                 case 2:
2890                 {
2891                         result=update_driver_init_2(printer.info_2);
2892                         break;
2893                 }
2894                 default:
2895                         result=1;
2896                         break;
2897         }
2898         
2899         return result;
2900 }
2901
2902 /****************************************************************************
2903  Convert the printer data value, a REG_BINARY array, into an initialization 
2904  DEVMODE. Note: the array must be parsed as if it was a DEVMODE in an rpc...
2905  got to keep the endians happy :).
2906 ****************************************************************************/
2907
2908 static BOOL convert_driver_init(NT_PRINTER_PARAM *param, TALLOC_CTX *ctx, NT_DEVICEMODE *nt_devmode)
2909 {
2910         BOOL       result = False;
2911         prs_struct ps;
2912         DEVICEMODE devmode;
2913
2914         ZERO_STRUCT(devmode);
2915
2916         prs_init(&ps, 0, ctx, UNMARSHALL);
2917         ps.data_p      = (char *)param->data;
2918         ps.buffer_size = param->data_len;
2919
2920         if (spoolss_io_devmode("phantom DEVMODE", &ps, 0, &devmode))
2921                 result = convert_devicemode("", &devmode, &nt_devmode);
2922         else
2923                 DEBUG(10,("convert_driver_init: error parsing DEVMODE\n"));
2924
2925         return result;
2926 }
2927
2928 /****************************************************************************
2929  Set the DRIVER_INIT info in the tdb. Requires Win32 client code that:
2930
2931  1. Use the driver's config DLL to this UNC printername and:
2932     a. Call DrvPrintEvent with PRINTER_EVENT_INITIALIZE
2933     b. Call DrvConvertDevMode with CDM_DRIVER_DEFAULT to get default DEVMODE
2934  2. Call SetPrinterData with the 'magic' key and the DEVMODE as data.
2935
2936  The last step triggers saving the "driver initialization" information for
2937  this printer into the tdb. Later, new printers that use this driver will
2938  have this initialization information bound to them. This simulates the
2939  driver initialization, as if it had run on the Samba server (as it would
2940  have done on NT).
2941
2942  The Win32 client side code requirement sucks! But until we can run arbitrary
2943  Win32 printer driver code on any Unix that Samba runs on, we are stuck with it.
2944  
2945  It would have been easier to use SetPrinter because all the UNMARSHALLING of
2946  the DEVMODE is done there, but 2K/XP clients do not set the DEVMODE... think
2947  about it and you will realize why.  JRR 010720
2948 ****************************************************************************/
2949
2950 static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, NT_PRINTER_PARAM *param)
2951 {
2952         WERROR        status       = WERR_OK;
2953         TALLOC_CTX    *ctx         = NULL;
2954         NT_DEVICEMODE *nt_devmode  = NULL;
2955         NT_DEVICEMODE *tmp_devmode = printer->info_2->devmode;
2956         
2957         /*
2958          * Set devmode on printer info, so entire printer initialization can be 
2959          * saved to tdb.
2960          */
2961         if ((ctx = talloc_init()) == NULL)
2962                 return WERR_NOMEM;
2963
2964         if ((nt_devmode = (NT_DEVICEMODE*)malloc(sizeof(NT_DEVICEMODE))) == NULL) {
2965                 status = WERR_NOMEM;
2966                 goto done;
2967         }
2968         
2969         ZERO_STRUCTP(nt_devmode);
2970
2971         /*
2972          * The DEVMODE is held in the 'data' component of the param in raw binary.
2973          * Convert it to to a devmode structure
2974          */
2975         if (!convert_driver_init(param, ctx, nt_devmode)) {
2976                 DEBUG(10,("save_driver_init_2: error converting DEVMODE\n"));
2977                 status = WERR_INVALID_PARAM;
2978                 goto done;
2979         }
2980
2981         /*
2982          * Pack up and add (or update) the DEVMODE and any current printer data to
2983          * a 'driver init' element in the tdb
2984          * 
2985          */
2986         printer->info_2->devmode = nt_devmode;
2987         if (update_driver_init(*printer, 2)!=0) {
2988                 DEBUG(10,("save_driver_init_2: error updating DEVMODE\n"));
2989                 status = WERR_NOMEM;
2990                 goto done;
2991         }
2992         
2993         /*
2994          * If driver initialization info was successfully saved, set the current 
2995          * printer to match it. This allows initialization of the current printer 
2996          * as well as the driver.
2997          */
2998         status = mod_a_printer(*printer, 2);
2999         if (!W_ERROR_IS_OK(status)) {
3000                 DEBUG(10,("save_driver_init_2: error setting DEVMODE on printer [%s]\n",
3001                                   printer->info_2->printername));
3002         }
3003
3004   done:
3005         talloc_destroy(ctx);
3006         if (nt_devmode)
3007                 SAFE_FREE(nt_devmode->private);
3008         SAFE_FREE(nt_devmode);
3009         printer->info_2->devmode = tmp_devmode;
3010
3011         return status;
3012 }
3013
3014 /****************************************************************************
3015  Update the driver init info (DEVMODE and specifics) for a printer
3016 ****************************************************************************/
3017
3018 WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, NT_PRINTER_PARAM *param)
3019 {
3020         WERROR status = WERR_OK;
3021         
3022         switch (level)
3023         {
3024                 case 2:
3025                 {
3026                         status=save_driver_init_2(printer, param);
3027                         break;
3028                 }
3029                 default:
3030                         status=WERR_UNKNOWN_LEVEL;
3031                         break;
3032         }
3033         
3034         return status;
3035 }
3036
3037 /****************************************************************************
3038  Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
3039 ****************************************************************************/
3040
3041 WERROR get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename)
3042 {
3043         WERROR result;
3044         NT_PRINTER_INFO_LEVEL *printer = NULL;
3045         
3046         *pp_printer = NULL;
3047
3048         DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
3049
3050         switch (level)
3051         {
3052                 case 2:
3053                 {
3054                         if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
3055                                 DEBUG(0,("get_a_printer: malloc fail.\n"));
3056                                 return WERR_NOMEM;
3057                         }
3058                         ZERO_STRUCTP(printer);
3059                         result=get_a_printer_2(&printer->info_2, sharename);
3060                         if (W_ERROR_IS_OK(result)) {
3061                                 dump_a_printer(*printer, level);
3062                                 *pp_printer = printer;
3063                         } else {
3064                                 SAFE_FREE(printer);
3065                         }
3066                         break;
3067                 }
3068                 default:
3069                         result=WERR_UNKNOWN_LEVEL;
3070                         break;
3071         }
3072         
3073         DEBUG(10,("get_a_printer: [%s] level %u returning %s\n", sharename, (unsigned int)level, werror_str(result)));
3074
3075         return result;
3076 }
3077
3078 /****************************************************************************
3079  Deletes a NT_PRINTER_INFO_LEVEL struct.
3080 ****************************************************************************/
3081
3082 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
3083 {
3084         uint32 result;
3085         NT_PRINTER_INFO_LEVEL *printer = *pp_printer;
3086
3087         DEBUG(104,("freeing a printer at level [%d]\n", level));
3088
3089         if (printer == NULL)
3090                 return 0;
3091         
3092         switch (level)
3093         {
3094                 case 2:
3095                 {
3096                         if (printer->info_2 != NULL)
3097                         {
3098                                 free_nt_printer_info_level_2(&printer->info_2);
3099                                 result=0;
3100                         }
3101                         else
3102                         {
3103                                 result=4;
3104                         }
3105                         break;
3106                 }
3107                 default:
3108                         result=1;
3109                         break;
3110         }
3111
3112         SAFE_FREE(*pp_printer);
3113         return result;
3114 }
3115
3116 /****************************************************************************
3117 ****************************************************************************/
3118 uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
3119 {
3120         uint32 result;
3121         DEBUG(104,("adding a printer at level [%d]\n", level));
3122         dump_a_printer_driver(driver, level);
3123         
3124         switch (level)
3125         {
3126                 case 3:
3127                 {
3128                         result=add_a_printer_driver_3(driver.info_3);
3129                         break;
3130                 }
3131
3132                 case 6:
3133                 {
3134                         result=add_a_printer_driver_6(driver.info_6);
3135                         break;
3136                 }
3137                 default:
3138                         result=1;
3139                         break;
3140         }
3141         
3142         return result;
3143 }
3144 /****************************************************************************
3145 ****************************************************************************/
3146 WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
3147                             fstring printername, fstring architecture, uint32 version)
3148 {
3149         WERROR result;
3150         
3151         switch (level)
3152         {
3153                 case 3:
3154                 {
3155                         result=get_a_printer_driver_3(&driver->info_3, printername, architecture, version);
3156                         break;
3157                 }
3158                 default:
3159                         result=W_ERROR(1);
3160                         break;
3161         }
3162         
3163         if (W_ERROR_IS_OK(result))
3164                 dump_a_printer_driver(*driver, level);
3165         return result;
3166 }
3167
3168 /****************************************************************************
3169 ****************************************************************************/
3170 uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
3171 {
3172         uint32 result;
3173         
3174         switch (level)
3175         {
3176                 case 3:
3177                 {
3178                         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
3179                         if (driver.info_3 != NULL)
3180                         {
3181                                 info3=driver.info_3;
3182                                 SAFE_FREE(info3->dependentfiles);
3183                                 ZERO_STRUCTP(info3);
3184                                 SAFE_FREE(info3);
3185                                 result=0;
3186                         }
3187                         else
3188                         {
3189                                 result=4;
3190                         }
3191                         break;
3192                 }
3193                 case 6:
3194                 {
3195                         NT_PRINTER_DRIVER_INFO_LEVEL_6 *info6;
3196                         if (driver.info_6 != NULL)
3197                         {
3198                                 info6=driver.info_6;
3199                                 SAFE_FREE(info6->dependentfiles);
3200                                 SAFE_FREE(info6->previousnames);
3201                                 ZERO_STRUCTP(info6);
3202                                 SAFE_FREE(info6);
3203                                 result=0;
3204                         }
3205                         else
3206                         {
3207                                 result=4;
3208                         }
3209                         break;
3210                 }
3211                 default:
3212                         result=1;
3213                         break;
3214         }
3215         return result;
3216 }
3217
3218
3219 /****************************************************************************
3220   Determine whether or not a particular driver is currently assigned
3221   to a printer
3222 ****************************************************************************/
3223 BOOL printer_driver_in_use (char *arch, char *driver)
3224 {
3225         TDB_DATA kbuf, newkey, dbuf;
3226         NT_PRINTER_INFO_LEVEL_2 info;
3227         int ret;
3228
3229         if (!tdb_printers)
3230                 if (!nt_printing_init())
3231                         return False;
3232
3233         DEBUG(5,("printer_driver_in_use: Beginning search through printers.tdb...\n"));
3234         
3235         /* loop through the printers.tdb and check for the drivername */
3236         for (kbuf = tdb_firstkey(tdb_printers); kbuf.dptr;
3237              newkey = tdb_nextkey(tdb_printers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) 
3238         {
3239
3240                 dbuf = tdb_fetch(tdb_printers, kbuf);
3241                 if (!dbuf.dptr) 
3242                         continue;
3243
3244                 if (strncmp(kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) != 0) 
3245                         continue;
3246
3247                 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddddddfffffPfffff",
3248                         &info.attributes,
3249                         &info.priority,
3250                         &info.default_priority,
3251                         &info.starttime,
3252                         &info.untiltime,
3253                         &info.status,
3254                         &info.cjobs,
3255                         &info.averageppm,
3256                         &info.changeid,
3257                         &info.c_setprinter,
3258                         &info.setuptime,
3259                         info.servername,
3260                         info.printername,
3261                         info.sharename,
3262                         info.portname,
3263                         info.drivername,
3264                         info.comment,
3265                         info.location,
3266                         info.sepfile,
3267                         info.printprocessor,
3268                         info.datatype,
3269                         info.parameters);
3270
3271                 SAFE_FREE(dbuf.dptr);
3272
3273                 if (ret == -1) {
3274                         DEBUG (0,("printer_driver_in_use: tdb_unpack failed for printer %s\n",
3275                                         info.printername));
3276                         continue;
3277                 }
3278                 
3279                 DEBUG (10,("printer_driver_in_use: Printer - %s (%s)\n",
3280                         info.printername, info.drivername));
3281                         
3282                 if (strcmp(info.drivername, driver) == 0) 
3283                 {
3284                         DEBUG(5,("printer_driver_in_use: Printer %s using %s\n",
3285                                 info.printername, driver));
3286                         return True;
3287                 }       
3288         }
3289         DEBUG(5,("printer_driver_in_use: Completed search through printers.tdb...\n"));
3290         
3291         
3292         
3293         /* report that the driver is in use by default */
3294         return False;
3295 }
3296
3297 /****************************************************************************
3298  Remove a printer driver from the TDB.  This assumes that the the driver was
3299  previously looked up.
3300  ***************************************************************************/
3301 WERROR delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i)
3302 {
3303         pstring         key;
3304         fstring         arch;
3305         TDB_DATA        kbuf;
3306
3307
3308         get_short_archi(arch, i->environment);
3309         slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX,
3310                 arch, i->cversion, i->name); 
3311         DEBUG(5,("delete_printer_driver: key = [%s]\n", key));
3312
3313         kbuf.dptr=key;
3314         kbuf.dsize=strlen(key)+1;
3315
3316         if (tdb_delete(tdb_drivers, kbuf) == -1) {
3317                 DEBUG (0,("delete_printer_driver: fail to delete %s!\n", key));
3318                 return WERR_ACCESS_DENIED;
3319         }
3320         
3321         DEBUG(5,("delete_printer_driver: [%s] driver delete successful.\n",
3322                 i->name));
3323         
3324         return WERR_OK;
3325 }
3326 /****************************************************************************
3327 ****************************************************************************/
3328 BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
3329                                  fstring value, uint8 **data, uint32 *type, uint32 *len)
3330 {
3331         /* right now that's enough ! */ 
3332         NT_PRINTER_PARAM *param;
3333         int i=0;
3334         
3335         param=printer.info_2->specific;
3336         
3337         while (param != NULL && i < param_index) {
3338                 param=param->next;
3339                 i++;
3340         }
3341         
3342         if (param == NULL)
3343                 return False;
3344
3345         /* exited because it exist */
3346         *type=param->type;              
3347         StrnCpy(value, param->value, sizeof(fstring)-1);
3348         *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
3349         if(*data == NULL)
3350                 return False;
3351         ZERO_STRUCTP(*data);
3352         memcpy(*data, param->data, param->data_len);
3353         *len=param->data_len;
3354         return True;
3355 }
3356
3357 /****************************************************************************
3358 ****************************************************************************/
3359 BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level,
3360                         fstring value, uint8 **data, uint32 *type, uint32 *len)
3361 {
3362         /* right now that's enough ! */ 
3363         NT_PRINTER_PARAM *param;
3364         
3365         DEBUG(10, ("get_specific_param\n"));
3366         
3367         param=printer.info_2->specific;
3368                 
3369         while (param != NULL)
3370         {
3371 #if 1 /* JRA - I think this should be case insensitive.... */
3372                 if ( strequal(value, param->value)
3373 #else
3374                 if ( !strcmp(value, param->value)
3375 #endif
3376                     && strlen(value)==strlen(param->value))
3377                         break;
3378                         
3379                 param=param->next;
3380         }
3381         
3382         if (param != NULL)
3383         {
3384         DEBUGADD(10, ("get_specific_param: found one param\n"));
3385                 /* exited because it exist */
3386                 *type=param->type;      
3387                 
3388                 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
3389                 if(*data == NULL)
3390                         return False;
3391                 memcpy(*data, param->data, param->data_len);
3392                 *len=param->data_len;
3393
3394                 DEBUGADD(10, ("get_specific_param: exit true\n"));
3395                 return (True);
3396         }
3397         DEBUGADD(10, ("get_specific_param: exit false\n"));
3398         return (False);
3399 }
3400
3401 /****************************************************************************
3402  Store a security desc for a printer.
3403 ****************************************************************************/
3404
3405 WERROR nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
3406 {
3407         SEC_DESC_BUF *new_secdesc_ctr = NULL;
3408         SEC_DESC_BUF *old_secdesc_ctr = NULL;
3409         prs_struct ps;
3410         TALLOC_CTX *mem_ctx = NULL;
3411         fstring key;
3412         WERROR status;
3413
3414         mem_ctx = talloc_init();
3415         if (mem_ctx == NULL)
3416                 return WERR_NOMEM;
3417
3418         /* The old owner and group sids of the security descriptor are not
3419            present when new ACEs are added or removed by changing printer
3420            permissions through NT.  If they are NULL in the new security
3421            descriptor then copy them over from the old one. */
3422
3423         if (!secdesc_ctr->sec->owner_sid || !secdesc_ctr->sec->grp_sid) {
3424                 DOM_SID *owner_sid, *group_sid;
3425                 SEC_ACL *dacl, *sacl;
3426                 SEC_DESC *psd = NULL;
3427                 size_t size;
3428
3429                 nt_printing_getsec(mem_ctx, printername, &old_secdesc_ctr);
3430
3431                 /* Pick out correct owner and group sids */
3432
3433                 owner_sid = secdesc_ctr->sec->owner_sid ?
3434                         secdesc_ctr->sec->owner_sid :
3435                         old_secdesc_ctr->sec->owner_sid;
3436
3437                 group_sid = secdesc_ctr->sec->grp_sid ?
3438                         secdesc_ctr->sec->grp_sid :
3439                         old_secdesc_ctr->sec->grp_sid;
3440
3441                 dacl = secdesc_ctr->sec->dacl ?
3442                         secdesc_ctr->sec->dacl :
3443                         old_secdesc_ctr->sec->dacl;
3444
3445                 sacl = secdesc_ctr->sec->sacl ?
3446                         secdesc_ctr->sec->sacl :
3447                         old_secdesc_ctr->sec->sacl;
3448
3449                 /* Make a deep copy of the security descriptor */
3450
3451                 psd = make_sec_desc(mem_ctx, secdesc_ctr->sec->revision,
3452                                     owner_sid, group_sid,
3453                                     sacl,
3454                                     dacl,
3455                                     &size);
3456
3457                 new_secdesc_ctr = make_sec_desc_buf(mem_ctx, size, psd);
3458         }
3459
3460         if (!new_secdesc_ctr) {
3461                 new_secdesc_ctr = secdesc_ctr;
3462         }
3463
3464         /* Store the security descriptor in a tdb */
3465
3466         prs_init(&ps, (uint32)sec_desc_size(new_secdesc_ctr->sec) +
3467                  sizeof(SEC_DESC_BUF), mem_ctx, MARSHALL);
3468
3469         if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr,
3470                              &ps, 1)) {
3471                 status = WERR_BADFUNC;
3472                 goto out;
3473         }
3474
3475         slprintf(key, sizeof(key)-1, "SECDESC/%s", printername);
3476
3477         if (tdb_prs_store(tdb_printers, key, &ps)==0) {
3478                 status = WERR_OK;
3479         } else {
3480                 DEBUG(1,("Failed to store secdesc for %s\n", printername));
3481                 status = WERR_BADFUNC;
3482         }
3483
3484         /* Free malloc'ed memory */
3485
3486  out:
3487
3488         prs_mem_free(&ps);
3489         if (mem_ctx)
3490                 talloc_destroy(mem_ctx);
3491         return status;
3492 }
3493
3494 /****************************************************************************
3495  Construct a default security descriptor buffer for a printer.
3496 ****************************************************************************/
3497
3498 static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
3499 {
3500         SEC_ACE ace[3];
3501         SEC_ACCESS sa;
3502         SEC_ACL *psa = NULL;
3503         SEC_DESC_BUF *sdb = NULL;
3504         SEC_DESC *psd = NULL;
3505         DOM_SID owner_sid;
3506         size_t sd_size;
3507         enum SID_NAME_USE name_type;
3508
3509         /* Create an ACE where Everyone is allowed to print */
3510
3511         init_sec_access(&sa, PRINTER_ACE_PRINT);
3512         init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
3513                      sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
3514
3515         /* Make the security descriptor owned by the Administrators group
3516            on the PDC of the domain. */
3517
3518         if (winbind_lookup_name(lp_workgroup(), &owner_sid, &name_type)) {
3519                 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
3520         } else {
3521                 uint32 owner_rid;
3522
3523                 /* Backup plan - make printer owned by admins or root.
3524                    This should emulate a lanman printer as security
3525                    settings can't be changed. */
3526
3527                 sid_peek_rid(&owner_sid, &owner_rid);
3528
3529                 if (owner_rid != BUILTIN_ALIAS_RID_PRINT_OPS &&
3530                     owner_rid != BUILTIN_ALIAS_RID_ADMINS &&
3531                     owner_rid != DOMAIN_USER_RID_ADMIN &&
3532                     !lookup_name("root", &owner_sid, &name_type)) {
3533                         sid_copy(&owner_sid, &global_sid_World);
3534                 }
3535         }
3536
3537         init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
3538         init_sec_ace(&ace[1], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
3539                      sa, SEC_ACE_FLAG_OBJECT_INHERIT |
3540                      SEC_ACE_FLAG_INHERIT_ONLY);
3541
3542         init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
3543         init_sec_ace(&ace[2], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
3544                      sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
3545
3546         /* The ACL revision number in rpc_secdesc.h differs from the one
3547            created by NT when setting ACE entries in printer
3548            descriptors.  NT4 complains about the property being edited by a
3549            NT5 machine. */
3550
3551         if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) != NULL) {
3552                &nbs