2 * Unix SMB/Netbios implementation.
4 * RPC Pipe client / server routines
5 * Copyright (C) Andrew Tridgell 1992-2000,
6 * Copyright (C) Jean François Micouleau 1998-2000.
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.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 extern int DEBUGLEVEL;
26 extern pstring global_myname;
27 extern DOM_SID global_sid_World;
29 static TDB_CONTEXT *tdb; /* used for driver files */
31 #define FORMS_PREFIX "FORMS/"
32 #define DRIVERS_PREFIX "DRIVERS/"
33 #define PRINTERS_PREFIX "PRINTERS/"
35 #define NTDRIVERS_DATABASE_VERSION 1
37 /* Map generic permissions to printer object specific permissions */
39 struct generic_mapping printer_generic_mapping = {
46 /* We need one default form to support our default printer. Msoft adds the
47 forms it wants and in the ORDER it wants them (note: DEVMODE papersize is an
48 array index). Letter is always first, so (for the current code) additions
49 always put things in the correct order. */
50 static nt_forms_struct default_forms[] = {
51 {"Letter", 0x2, 0x34b5b, 0x44367, 0x0, 0x0, 0x34b5b, 0x44367},
53 {"Letter",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
54 {"Letter Small",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
55 {"Tabloid",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
56 {"Ledger",0x1,0x696b8,0x44368,0x0,0x0,0x696b8,0x44368},
57 {"Legal",0x1,0x34b5c,0x56d10,0x0,0x0,0x34b5c,0x56d10},
58 {"Statement",0x1,0x221b4,0x34b5c,0x0,0x0,0x221b4,0x34b5c},
59 {"Executive",0x1,0x2cf56,0x411cc,0x0,0x0,0x2cf56,0x411cc},
60 {"A3",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
61 {"A4",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
62 {"A4 Small",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
63 {"A5",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
64 {"B4 (JIS)",0x1,0x3ebe8,0x58de0,0x0,0x0,0x3ebe8,0x58de0},
65 {"B5 (JIS)",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
66 {"Folio",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
67 {"Quarto",0x1,0x347d8,0x43238,0x0,0x0,0x347d8,0x43238},
68 {"10x14",0x1,0x3e030,0x56d10,0x0,0x0,0x3e030,0x56d10},
69 {"11x17",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
70 {"Note",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
71 {"Envelope #9",0x1,0x18079,0x37091,0x0,0x0,0x18079,0x37091},
72 {"Envelope #10",0x1,0x19947,0x3ae94,0x0,0x0,0x19947,0x3ae94},
73 {"Envelope #11",0x1,0x1be7c,0x40565,0x0,0x0,0x1be7c,0x40565},
74 {"Envelope #12",0x1,0x1d74a,0x44368,0x0,0x0,0x1d74a,0x44368},
75 {"Envelope #14",0x1,0x1f018,0x47504,0x0,0x0,0x1f018,0x47504},
76 {"C size sheet",0x1,0x696b8,0x886d0,0x0,0x0,0x696b8,0x886d0},
77 {"D size sheet",0x1,0x886d0,0xd2d70,0x0,0x0,0x886d0,0xd2d70},
78 {"E size sheet",0x1,0xd2d70,0x110da0,0x0,0x0,0xd2d70,0x110da0},
79 {"Envelope DL",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
80 {"Envelope C5",0x1,0x278d0,0x37e88,0x0,0x0,0x278d0,0x37e88},
81 {"Envelope C3",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
82 {"Envelope C4",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
83 {"Envelope C6",0x1,0x1bd50,0x278d0,0x0,0x0,0x1bd50,0x278d0},
84 {"Envelope C65",0x1,0x1bd50,0x37e88,0x0,0x0,0x1bd50,0x37e88},
85 {"Envelope B4",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
86 {"Envelope B5",0x1,0x2af80,0x3d090,0x0,0x0,0x2af80,0x3d090},
87 {"Envelope B6",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
88 {"Envelope",0x1,0x1adb0,0x38270,0x0,0x0,0x1adb0,0x38270},
89 {"Envelope Monarch",0x1,0x18079,0x2e824,0x0,0x0,0x18079,0x2e824},
90 {"6 3/4 Envelope",0x1,0x167ab,0x284ec,0x0,0x0,0x167ab,0x284ec},
91 {"US Std Fanfold",0x1,0x5c3e1,0x44368,0x0,0x0,0x5c3e1,0x44368},
92 {"German Std Fanfold",0x1,0x34b5c,0x4a6a0,0x0,0x0,0x34b5c,0x4a6a0},
93 {"German Legal Fanfold",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
94 {"B4 (ISO)",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
95 {"Japanese Postcard",0x1,0x186a0,0x24220,0x0,0x0,0x186a0,0x24220},
96 {"9x11",0x1,0x37cf8,0x44368,0x0,0x0,0x37cf8,0x44368},
97 {"10x11",0x1,0x3e030,0x44368,0x0,0x0,0x3e030,0x44368},
98 {"15x11",0x1,0x5d048,0x44368,0x0,0x0,0x5d048,0x44368},
99 {"Envelope Invite",0x1,0x35b60,0x35b60,0x0,0x0,0x35b60,0x35b60},
100 {"Reserved48",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
101 {"Reserved49",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
102 {"Letter Extra",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
103 {"Legal Extra",0x1,0x3ae94,0x5d048,0x0,0x0,0x3ae94,0x5d048},
104 {"Tabloid Extra",0x1,0x4a6a0,0x6f9f0,0x0,0x0,0x4a6a0,0x6f9f0},
105 {"A4 Extra",0x1,0x397c2,0x4eb16,0x0,0x0,0x397c2,0x4eb16},
106 {"Letter Transverse",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
107 {"A4 Transverse",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
108 {"Letter Extra Transverse",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
109 {"Super A",0x1,0x376b8,0x56ea0,0x0,0x0,0x376b8,0x56ea0},
110 {"Super B",0x1,0x4a768,0x76e58,0x0,0x0,0x4a768,0x76e58},
111 {"Letter Plus",0x1,0x34b5c,0x4eb16,0x0,0x0,0x34b5c,0x4eb16},
112 {"A4 Plus",0x1,0x33450,0x50910,0x0,0x0,0x33450,0x50910},
113 {"A5 Transverse",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
114 {"B5 (JIS) Transverse",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
115 {"A3 Extra",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
116 {"A5 Extra",0x1,0x2a7b0,0x395f8,0x0,0x0,0x2a7b0,0x395f8},
117 {"B5 (ISO) Extra",0x1,0x31128,0x43620,0x0,0x0,0x31128,0x43620},
118 {"A2",0x1,0x668a0,0x91050,0x0,0x0,0x668a0,0x91050},
119 {"A3 Transverse",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
120 {"A3 Extra Transverse",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
121 {"Japanese Double Postcard",0x1,0x30d40,0x24220,0x0,0x0,0x30d40,0x24220},
122 {"A6",0x1,0x19a28,0x24220,0x0,0x0,0x19a28,0x24220},
123 {"Japanese Envelope Kaku #2",0x1,0x3a980,0x510e0,0x0,0x0,0x3a980,0x510e0},
124 {"Japanese Envelope Kaku #3",0x1,0x34bc0,0x43a08,0x0,0x0,0x34bc0,0x43a08},
125 {"Japanese Envelope Chou #3",0x1,0x1d4c0,0x395f8,0x0,0x0,0x1d4c0,0x395f8},
126 {"Japanese Envelope Chou #4",0x1,0x15f90,0x320c8,0x0,0x0,0x15f90,0x320c8},
127 {"Letter Rotated",0x1,0x44368,0x34b5c,0x0,0x0,0x44368,0x34b5c},
128 {"A3 Rotated",0x1,0x668a0,0x48828,0x0,0x0,0x668a0,0x48828},
129 {"A4 Rotated",0x1,0x48828,0x33450,0x0,0x0,0x48828,0x33450},
130 {"A5 Rotated",0x1,0x33450,0x24220,0x0,0x0,0x33450,0x24220},
131 {"B4 (JIS) Rotated",0x1,0x58de0,0x3ebe8,0x0,0x0,0x58de0,0x3ebe8},
132 {"B5 (JIS) Rotated",0x1,0x3ebe8,0x2c6f0,0x0,0x0,0x3ebe8,0x2c6f0},
133 {"Japanese Postcard Rotated",0x1,0x24220,0x186a0,0x0,0x0,0x24220,0x186a0},
134 {"Double Japan Postcard Rotated",0x1,0x24220,0x30d40,0x0,0x0,0x24220,0x30d40},
135 {"A6 Rotated",0x1,0x24220,0x19a28,0x0,0x0,0x24220,0x19a28},
136 {"Japan Envelope Kaku #2 Rotated",0x1,0x510e0,0x3a980,0x0,0x0,0x510e0,0x3a980},
137 {"Japan Envelope Kaku #3 Rotated",0x1,0x43a08,0x34bc0,0x0,0x0,0x43a08, 0x34bc0},
138 {"Japan Envelope Chou #3 Rotated",0x1,0x395f8,0x1d4c0,0x0,0x0,0x395f8,0x1d4c0},
139 {"Japan Envelope Chou #4 Rotated",0x1,0x320c8,0x15f90,0x0,0x0,0x320c8,0x15f90},
140 {"B6 (JIS)",0x1,0x1f400,0x2c6f0,0x0,0x0,0x1f400,0x2c6f0},
141 {"B6 (JIS) Rotated",0x1,0x2c6f0,0x1f400,0x0,0x0,0x2c6f0,0x1f400},
142 {"12x11",0x1,0x4a724,0x443e1,0x0,0x0,0x4a724,0x443e1},
143 {"Japan Envelope You #4",0x1,0x19a28,0x395f8,0x0,0x0,0x19a28,0x395f8},
144 {"Japan Envelope You #4 Rotated",0x1,0x395f8,0x19a28,0x0,0x0,0x395f8,0x19a28},
145 {"PRC 16K",0x1,0x2de60,0x3f7a0,0x0,0x0,0x2de60,0x3f7a0},
146 {"PRC 32K",0x1,0x1fbd0,0x2cec0,0x0,0x0,0x1fbd0,0x2cec0},
147 {"PRC 32K(Big)",0x1,0x222e0,0x318f8,0x0,0x0,0x222e0,0x318f8},
148 {"PRC Envelope #1",0x1,0x18e70,0x28488,0x0,0x0,0x18e70,0x28488},
149 {"PRC Envelope #2",0x1,0x18e70,0x2af80,0x0,0x0,0x18e70,0x2af80},
150 {"PRC Envelope #3",0x1,0x1e848,0x2af80,0x0,0x0,0x1e848,0x2af80},
151 {"PRC Envelope #4",0x1,0x1adb0,0x32c80,0x0,0x0,0x1adb0,0x32c80},
152 {"PRC Envelope #5",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
153 {"PRC Envelope #6",0x1,0x1d4c0,0x38270,0x0,0x0,0x1d4c0,0x38270},
154 {"PRC Envelope #7",0x1,0x27100,0x38270,0x0,0x0,0x27100,0x38270},
155 {"PRC Envelope #8",0x1,0x1d4c0,0x4b708,0x0,0x0,0x1d4c0,0x4b708},
156 {"PRC Envelope #9",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
157 {"PRC Envelope #10",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
158 {"PRC 16K Rotated",0x1,0x3f7a0,0x2de60,0x0,0x0,0x3f7a0,0x2de60},
159 {"PRC 32K Rotated",0x1,0x2cec0,0x1fbd0,0x0,0x0,0x2cec0,0x1fbd0},
160 {"PRC 32K(Big) Rotated",0x1,0x318f8,0x222e0,0x0,0x0,0x318f8,0x222e0},
161 {"PRC Envelope #1 Rotated",0x1,0x28488,0x18e70,0x0,0x0,0x28488,0x18e70},
162 {"PRC Envelope #2 Rotated",0x1,0x2af80,0x18e70,0x0,0x0,0x2af80,0x18e70},
163 {"PRC Envelope #3 Rotated",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
164 {"PRC Envelope #4 Rotated",0x1,0x32c80,0x1adb0,0x0,0x0,0x32c80,0x1adb0},
165 {"PRC Envelope #5 Rotated",0x1,0x35b60,0x1adb0,0x0,0x0,0x35b60,0x1adb0},
166 {"PRC Envelope #6 Rotated",0x1,0x38270,0x1d4c0,0x0,0x0,0x38270,0x1d4c0},
167 {"PRC Envelope #7 Rotated",0x1,0x38270,0x27100,0x0,0x0,0x38270,0x27100},
168 {"PRC Envelope #8 Rotated",0x1,0x4b708,0x1d4c0,0x0,0x0,0x4b708,0x1d4c0},
169 {"PRC Envelope #9 Rotated",0x1,0x4f1a0,0x37e88,0x0,0x0,0x4f1a0,0x37e88},
170 {"PRC Envelope #10 Rotated",0x1,0x6fd10,0x4f1a0,0x0,0x0,0x6fd10,0x4f1a0}
174 /****************************************************************************
175 open the NT printing tdb
176 ****************************************************************************/
177 BOOL nt_printing_init(void)
179 static pid_t local_pid;
180 char *vstring = "INFO/version";
182 if (tdb && local_pid == sys_getpid()) return True;
183 tdb = tdb_open_log(lock_path("ntdrivers.tdb"), 0, 0, O_RDWR|O_CREAT, 0600);
185 DEBUG(0,("Failed to open nt drivers database %s (%s)\n",
186 lock_path("ntdrivers.tdb"), strerror(errno) ));
190 local_pid = sys_getpid();
192 /* handle a Samba upgrade */
193 tdb_lock_bystring(tdb, vstring);
194 if (tdb_fetch_int(tdb, vstring) != NTDRIVERS_DATABASE_VERSION) {
195 tdb_traverse(tdb, (tdb_traverse_func)tdb_delete, NULL);
196 tdb_store_int(tdb, vstring, NTDRIVERS_DATABASE_VERSION);
198 tdb_unlock_bystring(tdb, vstring);
203 /****************************************************************************
204 get builtin form struct list
205 ****************************************************************************/
206 int get_builtin_ntforms(nt_forms_struct **list)
208 *list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));
209 return sizeof(default_forms) / sizeof(default_forms[0]);
212 /****************************************************************************
213 get a builtin form struct
214 ****************************************************************************/
216 BOOL get_a_builtin_ntform(UNISTR2 *uni_formname,nt_forms_struct *form)
220 unistr2_to_ascii(form_name, uni_formname, sizeof(form_name)-1);
221 DEBUGADD(6,("Looking for builtin form %s \n", form_name));
222 count = sizeof(default_forms) / sizeof(default_forms[0]);
223 for (i=0;i<count;i++) {
224 if (strequal(form_name,default_forms[i].name)) {
225 DEBUGADD(6,("Found builtin form %s \n", form_name));
226 memcpy(form,&default_forms[i],sizeof(*form));
234 /****************************************************************************
235 get a form struct list
236 ****************************************************************************/
237 int get_ntforms(nt_forms_struct **list)
239 TDB_DATA kbuf, newkey, dbuf;
240 nt_forms_struct form;
245 for (kbuf = tdb_firstkey(tdb);
247 newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
248 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0) continue;
250 dbuf = tdb_fetch(tdb, kbuf);
251 if (!dbuf.dptr) continue;
253 fstrcpy(form.name, kbuf.dptr+strlen(FORMS_PREFIX));
254 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddd",
255 &i, &form.flag, &form.width, &form.length, &form.left,
256 &form.top, &form.right, &form.bottom);
257 safe_free(dbuf.dptr);
258 if (ret != dbuf.dsize) continue;
260 *list = Realloc(*list, sizeof(nt_forms_struct)*(n+1));
262 DEBUG(0,("get_ntforms: Realloc fail.\n"));
273 /****************************************************************************
274 write a form struct list
275 ****************************************************************************/
276 int write_ntforms(nt_forms_struct **list, int number)
283 for (i=0;i<number;i++) {
284 /* save index, so list is rebuilt in correct order */
285 len = tdb_pack(buf, sizeof(buf), "dddddddd",
286 i, (*list)[i].flag, (*list)[i].width, (*list)[i].length,
287 (*list)[i].left, (*list)[i].top, (*list)[i].right,
289 if (len > sizeof(buf)) break;
290 slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[i].name);
291 kbuf.dsize = strlen(key)+1;
295 if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) break;
301 /****************************************************************************
302 add a form struct at the end of the list
303 ****************************************************************************/
304 BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
311 * NT tries to add forms even when
312 * they are already in the base
313 * only update the values if already present
318 unistr2_to_ascii(form_name, &form->name, sizeof(form_name)-1);
319 for (n=0; n<*count; n++) {
320 if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
321 DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
328 if((*list=Realloc(*list, (n+1)*sizeof(nt_forms_struct))) == NULL)
330 unistr2_to_ascii((*list)[n].name, &form->name, sizeof((*list)[n].name)-1);
334 (*list)[n].flag=form->flags;
335 (*list)[n].width=form->size_x;
336 (*list)[n].length=form->size_y;
337 (*list)[n].left=form->left;
338 (*list)[n].top=form->top;
339 (*list)[n].right=form->right;
340 (*list)[n].bottom=form->bottom;
345 /****************************************************************************
346 delete a named form struct
347 ****************************************************************************/
348 BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, uint32 *ret)
357 unistr2_to_ascii(form_name, del_name, sizeof(form_name)-1);
359 for (n=0; n<*count; n++) {
360 if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
361 DEBUG(103, ("delete_a_form, [%s] in list\n", form_name));
367 DEBUG(10,("delete_a_form, [%s] not found\n", form_name));
368 *ret = ERROR_INVALID_PARAMETER;
372 slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[n].name);
373 kbuf.dsize = strlen(key)+1;
375 if (tdb_delete(tdb, kbuf) != 0) {
376 *ret = ERROR_NOT_ENOUGH_MEMORY;
383 /****************************************************************************
385 ****************************************************************************/
386 void update_a_form(nt_forms_struct **list, const FORM *form, int count)
390 unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
392 DEBUG(106, ("[%s]\n", form_name));
393 for (n=0; n<count; n++)
395 DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
396 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
400 if (n==count) return;
402 (*list)[n].flag=form->flags;
403 (*list)[n].width=form->size_x;
404 (*list)[n].length=form->size_y;
405 (*list)[n].left=form->left;
406 (*list)[n].top=form->top;
407 (*list)[n].right=form->right;
408 (*list)[n].bottom=form->bottom;
411 /****************************************************************************
412 get the nt drivers list
414 traverse the database and look-up the matching names
415 ****************************************************************************/
416 int get_ntdrivers(fstring **list, char *architecture, uint32 version)
421 TDB_DATA kbuf, newkey;
423 get_short_archi(short_archi, architecture);
424 slprintf(key, sizeof(key)-1, "%s%s/%d/", DRIVERS_PREFIX, short_archi, version);
426 for (kbuf = tdb_firstkey(tdb);
428 newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
429 if (strncmp(kbuf.dptr, key, strlen(key)) != 0) continue;
431 if((*list = Realloc(*list, sizeof(fstring)*(total+1))) == NULL)
434 fstrcpy((*list)[total], kbuf.dptr+strlen(key));
441 /****************************************************************************
442 function to do the mapping between the long architecture name and
444 ****************************************************************************/
445 BOOL get_short_archi(char *short_archi, char *long_archi)
452 struct table archi_table[]=
454 {"Windows 4.0", "WIN40" },
455 {"Windows NT x86", "W32X86" },
456 {"Windows NT R4000", "W32MIPS" },
457 {"Windows NT Alpha_AXP", "W32ALPHA" },
458 {"Windows NT PowerPC", "W32PPC" },
464 DEBUG(107,("Getting architecture dependant directory\n"));
467 } while ( (archi_table[i].long_archi!=NULL ) &&
468 StrCaseCmp(long_archi, archi_table[i].long_archi) );
470 if (archi_table[i].long_archi==NULL) {
471 DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
475 StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
477 DEBUGADD(108,("index: [%d]\n", i));
478 DEBUGADD(108,("long architecture: [%s]\n", long_archi));
479 DEBUGADD(108,("short architecture: [%s]\n", short_archi));
484 /****************************************************************************
485 Determine the correct cVersion associated with an architecture and driver
486 ****************************************************************************/
487 static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in,
488 struct current_user *user, uint32 *perr)
494 char buf[PE_HEADER_SIZE];
499 files_struct *fsp = NULL;
503 connection_struct *conn;
507 /* If architecture is Windows 95/98, the version is always 0. */
508 if (strcmp(architecture, "WIN40") == 0) {
509 DEBUG(10,("get_correct_cversion: Driver is Win9x, cversion = 0\n"));
514 pass = sys_getpwuid(user->uid);
516 DEBUG(0,("get_correct_cversion: Unable to get passwd entry for uid %u\n",
517 (unsigned int)user->uid ));
519 *perr = ERROR_ACCESS_DENIED;
524 /* connect to the print$ share under the same account as the user connected
526 fstrcpy(user_name, pass->pw_name );
527 DEBUG(10,("get_correct_cversion: uid %d -> user %s\n", (int)user->uid, user_name));
529 /* Null password is ok - we are already an authenticated user... */
531 conn = make_connection("print$", user_name, null_pw, 0, "A:", user->vuid, &ecode);
534 DEBUG(0,("get_correct_cversion: Unable to connect\n"));
535 *perr = (uint32)ecode;
539 /* Save who we are - we are temporarily becoming the connection user. */
542 if (!become_user(conn, conn->vuid)) {
543 DEBUG(0,("get_correct_cversion: Can't become user %s\n", user_name ));
544 *perr = ERROR_ACCESS_DENIED;
549 /* Open the driver file (Portable Executable format) and determine the
550 * deriver the cversion. */
551 slprintf(driverpath, sizeof(driverpath)-1, "%s/%s", architecture, driverpath_in);
553 unix_convert(driverpath,conn,NULL,&bad_path,&st);
555 fsp = open_file_shared(conn, driverpath, &st,
556 SET_OPEN_MODE(DOS_OPEN_RDONLY),
557 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
558 0, 0, &access_mode, &action);
560 DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
562 *perr = ERROR_ACCESS_DENIED;
566 if ((byte_count = vfs_read_data(fsp, buf, DOS_HEADER_SIZE)) < DOS_HEADER_SIZE) {
567 DEBUG(3,("get_correct_cversion: File [%s] DOS header too short, bytes read = %d\n",
568 driverpath, byte_count));
569 *perr = NT_STATUS_FILE_INVALID;
573 /* Is this really a DOS header? */
574 if (SVAL(buf,DOS_HEADER_MAGIC_OFFSET) != DOS_HEADER_MAGIC) {
575 DEBUG(6,("get_correct_cversion: File [%s] bad DOS magic = 0x%x\n",
576 driverpath, SVAL(buf,DOS_HEADER_MAGIC_OFFSET)));
577 *perr = NT_STATUS_FILE_INVALID;
581 /* Skip OEM header (if any) and the DOS stub to start of Windows header */
582 if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
583 DEBUG(3,("get_correct_cversion: File [%s] too short, errno = %d\n",
585 *perr = NT_STATUS_FILE_INVALID;
589 if ((byte_count = vfs_read_data(fsp, buf, PE_HEADER_SIZE)) < PE_HEADER_SIZE) {
590 DEBUG(3,("get_correct_cversion: File [%s] Windows header too short, bytes read = %d\n",
591 driverpath, byte_count));
592 *perr = NT_STATUS_FILE_INVALID;
596 /* The header may be a PE (Portable Executable) or an NE (New Executable) */
597 if (IVAL(buf,PE_HEADER_SIGNATURE_OFFSET) == PE_HEADER_SIGNATURE) {
598 if (SVAL(buf,PE_HEADER_MACHINE_OFFSET) == PE_HEADER_MACHINE_I386) {
600 switch (SVAL(buf,PE_HEADER_MAJOR_OS_VER_OFFSET)) {
601 case 4: cversion = 2; break; /* Win NT 4 */
602 case 5: cversion = 3; break; /* Win 2000 */
604 DEBUG(6,("get_correct_cversion: PE formated file [%s] bad version = %d\n",
605 driverpath, SVAL(buf,PE_HEADER_MAJOR_OS_VER_OFFSET)));
606 *perr = NT_STATUS_FILE_INVALID;
610 DEBUG(6,("get_correct_cversion: PE formatted file [%s] wrong machine = 0x%x\n",
611 driverpath, SVAL(buf,PE_HEADER_MACHINE_OFFSET)));
612 *perr = NT_STATUS_FILE_INVALID;
616 } else if (SVAL(buf,NE_HEADER_SIGNATURE_OFFSET) == NE_HEADER_SIGNATURE) {
617 if (CVAL(buf,NE_HEADER_TARGET_OS_OFFSET) == NE_HEADER_TARGOS_WIN ) {
619 switch (CVAL(buf,NE_HEADER_MAJOR_VER_OFFSET)) {
620 case 3: cversion = 0; break; /* Win 3.x / Win 9x / Win ME */
621 /* case ?: cversion = 1; break;*/ /* Win NT 3.51 ... needs research JRR */
623 DEBUG(6,("get_correct_cversion: NE formated file [%s] bad version = %d\n",
624 driverpath, CVAL(buf,NE_HEADER_MAJOR_VER_OFFSET)));
625 *perr = NT_STATUS_FILE_INVALID;
629 DEBUG(6,("get_correct_cversion: NE formatted file [%s] wrong target OS = 0x%x\n",
630 driverpath, CVAL(buf,NE_HEADER_TARGET_OS_OFFSET)));
631 *perr = NT_STATUS_FILE_INVALID;
636 DEBUG(6,("get_correct_cversion: Unknown file format [%s], signature = 0x%x\n",
637 driverpath, IVAL(buf,PE_HEADER_SIGNATURE_OFFSET)));
638 *perr = NT_STATUS_FILE_INVALID;
642 DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
643 driverpath, cversion));
645 close_file(fsp, True);
646 close_cnum(conn, user->vuid);
653 close_file(fsp, True);
655 close_cnum(conn, user->vuid);
660 /****************************************************************************
661 ****************************************************************************/
662 static uint32 clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver,
663 struct current_user *user)
665 fstring architecture;
671 /* clean up the driver name.
672 * we can get .\driver.dll
673 * or worse c:\windows\system\driver.dll !
675 /* using an intermediate string to not have overlaping memcpy()'s */
676 if ((p = strrchr_m(driver->driverpath,'\\')) != NULL) {
677 fstrcpy(new_name, p+1);
678 fstrcpy(driver->driverpath, new_name);
681 if ((p = strrchr_m(driver->datafile,'\\')) != NULL) {
682 fstrcpy(new_name, p+1);
683 fstrcpy(driver->datafile, new_name);
686 if ((p = strrchr_m(driver->configfile,'\\')) != NULL) {
687 fstrcpy(new_name, p+1);
688 fstrcpy(driver->configfile, new_name);
691 if ((p = strrchr_m(driver->helpfile,'\\')) != NULL) {
692 fstrcpy(new_name, p+1);
693 fstrcpy(driver->helpfile, new_name);
696 if (driver->dependentfiles) {
697 for (i=0; *driver->dependentfiles[i]; i++) {
698 if ((p = strrchr_m(driver->dependentfiles[i],'\\')) != NULL) {
699 fstrcpy(new_name, p+1);
700 fstrcpy(driver->dependentfiles[i], new_name);
705 get_short_archi(architecture, driver->environment);
707 /* jfm:7/16/2000 the client always sends the cversion=0.
708 * The server should check which version the driver is by reading
709 * the PE header of driver->driverpath.
711 * For Windows 95/98 the version is 0 (so the value sent is correct)
712 * For Windows NT (the architecture doesn't matter)
714 * NT 3.5/3.51: cversion=1
718 if ((driver->cversion = get_correct_cversion( architecture,
719 driver->driverpath, user, &err)) == -1)
722 return NT_STATUS_NO_PROBLEMO;
725 /****************************************************************************
726 ****************************************************************************/
727 static uint32 clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver,
728 struct current_user *user)
730 fstring architecture;
736 /* clean up the driver name.
737 * we can get .\driver.dll
738 * or worse c:\windows\system\driver.dll !
740 /* using an intermediate string to not have overlaping memcpy()'s */
741 if ((p = strrchr_m(driver->driverpath,'\\')) != NULL) {
742 fstrcpy(new_name, p+1);
743 fstrcpy(driver->driverpath, new_name);
746 if ((p = strrchr_m(driver->datafile,'\\')) != NULL) {
747 fstrcpy(new_name, p+1);
748 fstrcpy(driver->datafile, new_name);
751 if ((p = strrchr_m(driver->configfile,'\\')) != NULL) {
752 fstrcpy(new_name, p+1);
753 fstrcpy(driver->configfile, new_name);
756 if ((p = strrchr_m(driver->helpfile,'\\')) != NULL) {
757 fstrcpy(new_name, p+1);
758 fstrcpy(driver->helpfile, new_name);
761 if (driver->dependentfiles) {
762 for (i=0; *driver->dependentfiles[i]; i++) {
763 if ((p = strrchr_m(driver->dependentfiles[i],'\\')) != NULL) {
764 fstrcpy(new_name, p+1);
765 fstrcpy(driver->dependentfiles[i], new_name);
770 get_short_archi(architecture, driver->environment);
772 /* jfm:7/16/2000 the client always sends the cversion=0.
773 * The server should check which version the driver is by reading
774 * the PE header of driver->driverpath.
776 * For Windows 95/98 the version is 0 (so the value sent is correct)
777 * For Windows NT (the architecture doesn't matter)
779 * NT 3.5/3.51: cversion=1
783 if ((driver->version = get_correct_cversion(architecture,
784 driver->driverpath, user, &err)) == -1)
787 return NT_STATUS_NO_PROBLEMO;
790 /****************************************************************************
791 ****************************************************************************/
792 uint32 clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
793 uint32 level, struct current_user *user)
798 NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
799 driver=driver_abstract.info_3;
800 return clean_up_driver_struct_level_3(driver, user);
804 NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver;
805 driver=driver_abstract.info_6;
806 return clean_up_driver_struct_level_6(driver, user);
809 return ERROR_INVALID_PARAMETER;
813 /****************************************************************************
814 This function sucks and should be replaced. JRA.
815 ****************************************************************************/
817 static void convert_level_6_to_level3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dst, NT_PRINTER_DRIVER_INFO_LEVEL_6 *src)
819 dst->cversion = src->version;
821 fstrcpy( dst->name, src->name);
822 fstrcpy( dst->environment, src->environment);
823 fstrcpy( dst->driverpath, src->driverpath);
824 fstrcpy( dst->datafile, src->datafile);
825 fstrcpy( dst->configfile, src->configfile);
826 fstrcpy( dst->helpfile, src->helpfile);
827 fstrcpy( dst->monitorname, src->monitorname);
828 fstrcpy( dst->defaultdatatype, src->defaultdatatype);
829 dst->dependentfiles = src->dependentfiles;
832 #if 0 /* Debugging function */
834 static char* ffmt(unsigned char *c){
836 static char ffmt_str[17];
838 for (i=0; i<16; i++) {
839 if ((c[i] < ' ') || (c[i] > '~'))
850 /****************************************************************************
851 Version information in Microsoft files is held in a VS_VERSION_INFO structure.
852 There are two case to be covered here: PE (Portable Executable) and NE (New
853 Executable) files. Both files support the same INFO structure, but PE files
854 store the signature in unicode, and NE files store it as !unicode.
855 ****************************************************************************/
856 static BOOL get_file_version(files_struct *fsp, char *fname,uint32 *major,
863 if ((buf=malloc(PE_HEADER_SIZE)) == NULL) {
864 DEBUG(0,("get_file_version: PE file [%s] PE Header malloc failed bytes = %d\n",
865 fname, PE_HEADER_SIZE));
869 /* Note: DOS_HEADER_SIZE < malloc'ed PE_HEADER_SIZE */
870 if ((byte_count = vfs_read_data(fsp, buf, DOS_HEADER_SIZE)) < DOS_HEADER_SIZE) {
871 DEBUG(3,("get_file_version: File [%s] DOS header too short, bytes read = %d\n",
873 goto no_version_info;
876 /* Is this really a DOS header? */
877 if (SVAL(buf,DOS_HEADER_MAGIC_OFFSET) != DOS_HEADER_MAGIC) {
878 DEBUG(6,("get_file_version: File [%s] bad DOS magic = 0x%x\n",
879 fname, SVAL(buf,DOS_HEADER_MAGIC_OFFSET)));
880 goto no_version_info;
883 /* Skip OEM header (if any) and the DOS stub to start of Windows header */
884 if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
885 DEBUG(3,("get_file_version: File [%s] too short, errno = %d\n",
887 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
888 goto no_version_info;
891 if ((byte_count = vfs_read_data(fsp, buf, PE_HEADER_SIZE)) < PE_HEADER_SIZE) {
892 DEBUG(3,("get_file_version: File [%s] Windows header too short, bytes read = %d\n",
894 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
895 goto no_version_info;
898 /* The header may be a PE (Portable Executable) or an NE (New Executable) */
899 if (IVAL(buf,PE_HEADER_SIGNATURE_OFFSET) == PE_HEADER_SIGNATURE) {
901 int section_table_bytes;
903 if (SVAL(buf,PE_HEADER_MACHINE_OFFSET) != PE_HEADER_MACHINE_I386) {
904 DEBUG(3,("get_file_version: PE file [%s] wrong machine = 0x%x\n",
905 fname, SVAL(buf,PE_HEADER_MACHINE_OFFSET)));
906 /* At this point, we assume the file is in error. It still could be somthing
907 * else besides a PE file, but it unlikely at this point.
912 /* get the section table */
913 num_sections = SVAL(buf,PE_HEADER_NUMBER_OF_SECTIONS);
914 section_table_bytes = num_sections * PE_HEADER_SECT_HEADER_SIZE;
916 if ((buf=malloc(section_table_bytes)) == NULL) {
917 DEBUG(0,("get_file_version: PE file [%s] section table malloc failed bytes = %d\n",
918 fname, section_table_bytes));
922 if ((byte_count = vfs_read_data(fsp, buf, section_table_bytes)) < section_table_bytes) {
923 DEBUG(3,("get_file_version: PE file [%s] Section header too short, bytes read = %d\n",
928 /* Iterate the section table looking for the resource section ".rsrc" */
929 for (i = 0; i < num_sections; i++) {
930 int sec_offset = i * PE_HEADER_SECT_HEADER_SIZE;
932 if (strcmp(".rsrc", &buf[sec_offset+PE_HEADER_SECT_NAME_OFFSET]) == 0) {
933 int section_pos = IVAL(buf,sec_offset+PE_HEADER_SECT_PTR_DATA_OFFSET);
934 int section_bytes = IVAL(buf,sec_offset+PE_HEADER_SECT_SIZE_DATA_OFFSET);
937 if ((buf=malloc(section_bytes)) == NULL) {
938 DEBUG(0,("get_file_version: PE file [%s] version malloc failed bytes = %d\n",
939 fname, section_bytes));
943 /* Seek to the start of the .rsrc section info */
944 if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, section_pos, SEEK_SET) == (SMB_OFF_T)-1) {
945 DEBUG(3,("get_file_version: PE file [%s] too short for section info, errno = %d\n",
950 if ((byte_count = vfs_read_data(fsp, buf, section_bytes)) < section_bytes) {
951 DEBUG(3,("get_file_version: PE file [%s] .rsrc section too short, bytes read = %d\n",
956 for (i=0; i<section_bytes-VS_VERSION_INFO_UNICODE_SIZE; i++) {
957 /* Scan for 1st 3 unicoded bytes followed by word aligned magic value */
958 if (buf[i] == 'V' && buf[i+1] == '\0' && buf[i+2] == 'S') {
959 /* Align to next long address */
960 int pos = (i + sizeof(VS_SIGNATURE)*2 + 3) & 0xfffffffc;
962 if (IVAL(buf,pos) == VS_MAGIC_VALUE) {
963 *major = IVAL(buf,pos+VS_MAJOR_OFFSET);
964 *minor = IVAL(buf,pos+VS_MINOR_OFFSET);
966 DEBUG(6,("get_file_version: PE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
967 fname, *major, *minor,
968 (*major>>16)&0xffff, *major&0xffff,
969 (*minor>>16)&0xffff, *minor&0xffff));
978 /* Version info not found, fall back to origin date/time */
979 DEBUG(10,("get_file_version: PE file [%s] has no version info\n", fname));
983 } else if (SVAL(buf,NE_HEADER_SIGNATURE_OFFSET) == NE_HEADER_SIGNATURE) {
984 if (CVAL(buf,NE_HEADER_TARGET_OS_OFFSET) != NE_HEADER_TARGOS_WIN ) {
985 DEBUG(3,("get_file_version: NE file [%s] wrong target OS = 0x%x\n",
986 fname, CVAL(buf,NE_HEADER_TARGET_OS_OFFSET)));
987 /* At this point, we assume the file is in error. It still could be somthing
988 * else besides a NE file, but it unlikely at this point. */
992 /* Allocate a bit more space to speed up things */
994 if ((buf=malloc(VS_NE_BUF_SIZE)) == NULL) {
995 DEBUG(0,("get_file_version: NE file [%s] malloc failed bytes = %d\n",
996 fname, PE_HEADER_SIZE));
1000 /* This is a HACK! I got tired of trying to sort through the messy
1001 * 'NE' file format. If anyone wants to clean this up please have at
1002 * it, but this works. 'NE' files will eventually fade away. JRR */
1003 while((byte_count = vfs_read_data(fsp, buf, VS_NE_BUF_SIZE)) > 0) {
1004 /* Cover case that should not occur in a well formed 'NE' .dll file */
1005 if (byte_count-VS_VERSION_INFO_SIZE <= 0) break;
1007 for(i=0; i<byte_count; i++) {
1008 /* Fast skip past data that can't possibly match */
1009 if (buf[i] != 'V') continue;
1011 /* Potential match data crosses buf boundry, move it to beginning
1012 * of buf, and fill the buf with as much as it will hold. */
1013 if (i>byte_count-VS_VERSION_INFO_SIZE) {
1016 memcpy(buf, &buf[i], byte_count-i);
1017 if ((bc = vfs_read_data(fsp, &buf[byte_count-i], VS_NE_BUF_SIZE-
1018 (byte_count-i))) < 0) {
1020 DEBUG(0,("get_file_version: NE file [%s] Read error, errno=%d\n",
1025 byte_count = bc + (byte_count - i);
1026 if (byte_count<VS_VERSION_INFO_SIZE) break;
1031 /* Check that the full signature string and the magic number that
1032 * follows exist (not a perfect solution, but the chances that this
1033 * occurs in code is, well, remote. Yes I know I'm comparing the 'V'
1034 * twice, as it is simpler to read the code. */
1035 if (strcmp(&buf[i], VS_SIGNATURE) == 0) {
1036 /* Compute skip alignment to next long address */
1037 int skip = -(fsp->conn->vfs_ops.lseek(fsp, fsp->fd, 0, SEEK_CUR) - (byte_count - i) +
1038 sizeof(VS_SIGNATURE)) & 3;
1039 if (IVAL(buf,i+sizeof(VS_SIGNATURE)+skip) != 0xfeef04bd) continue;
1041 *major = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MAJOR_OFFSET);
1042 *minor = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MINOR_OFFSET);
1043 DEBUG(6,("get_file_version: NE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
1044 fname, *major, *minor,
1045 (*major>>16)&0xffff, *major&0xffff,
1046 (*minor>>16)&0xffff, *minor&0xffff));
1053 /* Version info not found, fall back to origin date/time */
1054 DEBUG(0,("get_file_version: NE file [%s] Version info not found\n", fname));
1059 /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
1060 DEBUG(3,("get_file_version: File [%s] unknown file format, signature = 0x%x\n",
1061 fname, IVAL(buf,PE_HEADER_SIGNATURE_OFFSET)));
1072 /****************************************************************************
1073 Drivers for Microsoft systems contain multiple files. Often, multiple drivers
1074 share one or more files. During the MS installation process files are checked
1075 to insure that only a newer version of a shared file is installed over an
1076 older version. There are several possibilities for this comparison. If there
1077 is no previous version, the new one is newer (obviously). If either file is
1078 missing the version info structure, compare the creation date (on Unix use
1079 the modification date). Otherwise chose the numerically larger version number.
1080 ****************************************************************************/
1081 static int file_version_is_newer(connection_struct *conn, fstring new_file,
1084 BOOL use_version = True;
1089 time_t new_create_time;
1093 time_t old_create_time;
1097 files_struct *fsp = NULL;
1099 SMB_STRUCT_STAT stat_buf;
1103 ZERO_STRUCT(stat_buf);
1104 new_create_time = (time_t)0;
1105 old_create_time = (time_t)0;
1107 /* Get file version info (if available) for previous file (if it exists) */
1108 pstrcpy(filepath, old_file);
1110 unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
1112 fsp = open_file_shared(conn, filepath, &stat_buf,
1113 SET_OPEN_MODE(DOS_OPEN_RDONLY),
1114 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
1115 0, 0, &access_mode, &action);
1117 /* Old file not found, so by definition new file is in fact newer */
1118 DEBUG(10,("file_version_is_newer: Can't open old file [%s], errno = %d\n",
1123 int ret = get_file_version(fsp, old_file, &old_major, &old_minor);
1124 if (ret == -1) goto error_exit;
1127 DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
1129 use_version = False;
1130 if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit;
1131 old_create_time = st.st_mtime;
1132 DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", old_create_time));
1135 close_file(fsp, True);
1137 /* Get file version info (if available) for new file */
1138 pstrcpy(filepath, new_file);
1139 unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
1141 fsp = open_file_shared(conn, filepath, &stat_buf,
1142 SET_OPEN_MODE(DOS_OPEN_RDONLY),
1143 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
1144 0, 0, &access_mode, &action);
1146 /* New file not found, this shouldn't occur if the caller did its job */
1147 DEBUG(3,("file_version_is_newer: Can't open new file [%s], errno = %d\n",
1152 int ret = get_file_version(fsp, new_file, &new_major, &new_minor);
1153 if (ret == -1) goto error_exit;
1156 DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
1158 use_version = False;
1159 if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit;
1160 new_create_time = st.st_mtime;
1161 DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", new_create_time));
1164 close_file(fsp, True);
1167 /* Compare versions and choose the larger version number */
1168 if (new_major > old_major ||
1169 (new_major == old_major && new_minor > old_minor)) {
1171 DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
1175 DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
1180 /* Compare modification time/dates and choose the newest time/date */
1181 if (new_create_time > old_create_time) {
1182 DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
1186 DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
1193 close_file(fsp, True);
1197 /****************************************************************************
1198 ****************************************************************************/
1199 BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level, struct current_user *user, uint32 *perr)
1201 NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
1202 NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver;
1203 fstring architecture;
1209 connection_struct *conn;
1212 struct passwd *pass;
1218 memset(inbuf, '\0', sizeof(inbuf));
1219 memset(outbuf, '\0', sizeof(outbuf));
1222 driver=driver_abstract.info_3;
1223 else if (level==6) {
1224 convert_level_6_to_level3(&converted_driver, driver_abstract.info_6);
1225 driver = &converted_driver;
1227 DEBUG(0,("move_driver_to_download_area: Unknown info level (%u)\n", (unsigned int)level ));
1231 get_short_archi(architecture, driver->environment);
1234 pass = sys_getpwuid(user->uid);
1236 DEBUG(0,("move_driver_to_download_area: Unable to get passwd entry for uid %u\n",
1237 (unsigned int)user->uid ));
1243 /* connect to the print$ share under the same account as the user connected to the rpc pipe */
1244 fstrcpy(user_name, pass->pw_name );
1245 DEBUG(10,("move_driver_to_download_area: uid %d -> user %s\n", (int)user->uid, user_name));
1247 /* Null password is ok - we are already an authenticated user... */
1249 conn = make_connection("print$", user_name, null_pw, 0, "A:", user->vuid, &ecode);
1252 DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
1253 *perr = (uint32)ecode;
1258 * Save who we are - we are temporarily becoming the connection user.
1263 if (!become_user(conn, conn->vuid)) {
1264 DEBUG(0,("move_driver_to_download_area: Can't become user %s\n", user_name ));
1270 * make the directories version and version\driver_name
1271 * under the architecture directory.
1273 DEBUG(5,("Creating first directory\n"));
1274 slprintf(new_dir, sizeof(new_dir)-1, "%s/%d", architecture, driver->cversion);
1275 mkdir_internal(conn, inbuf, outbuf, new_dir);
1277 /* For each driver file, archi\filexxx.yyy, if there is a duplicate file
1278 * listed for this driver which has already been moved, skip it (note:
1279 * drivers may list the same file name several times. Then check if the
1280 * file already exists in archi\cversion\, if so, check that the version
1281 * info (or time stamps if version info is unavailable) is newer (or the
1282 * date is later). If it is, move it to archi\cversion\filexxx.yyy.
1283 * Otherwise, delete the file.
1285 * If a file is not moved to archi\cversion\ because of an error, all the
1286 * rest of the 'unmoved' driver files are removed from archi\. If one or
1287 * more of the driver's files was already moved to archi\cversion\, it
1288 * potentially leaves the driver in a partially updated state. Version
1289 * trauma will most likely occur if an client attempts to use any printer
1290 * bound to the driver. Perhaps a rewrite to make sure the moves can be
1291 * done is appropriate... later JRR
1294 DEBUG(5,("Moving files now !\n"));
1296 if (driver->driverpath && strlen(driver->driverpath)) {
1297 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->driverpath);
1298 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->driverpath);
1299 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1300 if (rename_internals(conn, inbuf, outbuf, new_name, old_name, True) != 0) {
1301 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1302 new_name, old_name));
1303 *perr = (uint32)SVAL(outbuf,smb_err);
1304 unlink_internals(conn, inbuf, outbuf, 0, new_name);
1309 unlink_internals(conn, inbuf, outbuf, 0, new_name);
1312 if (driver->datafile && strlen(driver->datafile)) {
1313 if (!strequal(driver->datafile, driver->driverpath)) {
1314 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->datafile);
1315 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->datafile);
1316 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1317 if (rename_internals(conn, inbuf, outbuf, new_name, old_name, True) != 0) {
1318 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1319 new_name, old_name));
1320 *perr = (uint32)SVAL(outbuf,smb_err);
1321 unlink_internals(conn, inbuf, outbuf, 0, new_name);
1326 unlink_internals(conn, inbuf, outbuf, 0, new_name);
1330 if (driver->configfile && strlen(driver->configfile)) {
1331 if (!strequal(driver->configfile, driver->driverpath) &&
1332 !strequal(driver->configfile, driver->datafile)) {
1333 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->configfile);
1334 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->configfile);
1335 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1336 if (rename_internals(conn, inbuf, outbuf, new_name, old_name, True) != 0) {
1337 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1338 new_name, old_name));
1339 *perr = (uint32)SVAL(outbuf,smb_err);
1340 unlink_internals(conn, inbuf, outbuf, 0, new_name);
1345 unlink_internals(conn, inbuf, outbuf, 0, new_name);
1349 if (driver->helpfile && strlen(driver->helpfile)) {
1350 if (!strequal(driver->helpfile, driver->driverpath) &&
1351 !strequal(driver->helpfile, driver->datafile) &&
1352 !strequal(driver->helpfile, driver->configfile)) {
1353 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->helpfile);
1354 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->helpfile);
1355 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1356 if (rename_internals(conn, inbuf, outbuf, new_name, old_name, True) != 0) {
1357 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1358 new_name, old_name));
1359 *perr = (uint32)SVAL(outbuf,smb_err);
1360 unlink_internals(conn, inbuf, outbuf, 0, new_name);
1365 unlink_internals(conn, inbuf, outbuf, 0, new_name);
1369 if (driver->dependentfiles) {
1370 for (i=0; *driver->dependentfiles[i]; i++) {
1371 if (!strequal(driver->dependentfiles[i], driver->driverpath) &&
1372 !strequal(driver->dependentfiles[i], driver->datafile) &&
1373 !strequal(driver->dependentfiles[i], driver->configfile) &&
1374 !strequal(driver->dependentfiles[i], driver->helpfile)) {
1376 for (j=0; j < i; j++) {
1377 if (strequal(driver->dependentfiles[i], driver->dependentfiles[j])) {
1382 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->dependentfiles[i]);
1383 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->dependentfiles[i]);
1384 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
1385 if (rename_internals(conn, inbuf, outbuf, new_name, old_name, True) != 0) {
1386 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
1387 new_name, old_name));
1388 *perr = (uint32)SVAL(outbuf,smb_err);
1389 unlink_internals(conn, inbuf, outbuf, 0, new_name);
1394 unlink_internals(conn, inbuf, outbuf, 0, new_name);
1400 close_cnum(conn, user->vuid);
1403 return ver == -1 ? False : True;
1406 /****************************************************************************
1407 ****************************************************************************/
1408 static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
1411 fstring architecture;
1417 TDB_DATA kbuf, dbuf;
1419 get_short_archi(architecture, driver->environment);
1421 /* The names are relative. We store them in the form: \print$\arch\version\driver.xxx
1422 * \\server is added in the rpc server layer.
1423 * It does make sense to NOT store the server's name in the printer TDB.
1426 slprintf(directory, sizeof(directory)-1, "\\print$\\%s\\%d\\", architecture, driver->cversion);
1428 /* .inf files do not always list a file for each of the four standard files.
1429 * Don't prepend a path to a null filename, or client claims:
1430 * "The server on which the printer resides does not have a suitable
1431 * <printer driver name> printer driver installed. Click OK if you
1432 * wish to install the driver on your local machine."
1434 if (strlen(driver->driverpath)) {
1435 fstrcpy(temp_name, driver->driverpath);
1436 slprintf(driver->driverpath, sizeof(driver->driverpath)-1, "%s%s", directory, temp_name);
1439 if (strlen(driver->datafile)) {
1440 fstrcpy(temp_name, driver->datafile);
1441 slprintf(driver->datafile, sizeof(driver->datafile)-1, "%s%s", directory, temp_name);
1444 if (strlen(driver->configfile)) {
1445 fstrcpy(temp_name, driver->configfile);
1446 slprintf(driver->configfile, sizeof(driver->configfile)-1, "%s%s", directory, temp_name);
1449 if (strlen(driver->helpfile)) {
1450 fstrcpy(temp_name, driver->helpfile);
1451 slprintf(driver->helpfile, sizeof(driver->helpfile)-1, "%s%s", directory, temp_name);
1454 if (driver->dependentfiles) {
1455 for (i=0; *driver->dependentfiles[i]; i++) {
1456 fstrcpy(temp_name, driver->dependentfiles[i]);
1457 slprintf(driver->dependentfiles[i], sizeof(driver->dependentfiles[i])-1, "%s%s", directory, temp_name);
1461 slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, driver->cversion, driver->name);
1463 DEBUG(5,("add_a_printer_driver_3: Adding driver with key %s\n", key ));
1470 len += tdb_pack(buf+len, buflen-len, "dffffffff",
1473 driver->environment,
1478 driver->monitorname,
1479 driver->defaultdatatype);
1481 if (driver->dependentfiles) {
1482 for (i=0; *driver->dependentfiles[i]; i++) {
1483 len += tdb_pack(buf+len, buflen-len, "f",
1484 driver->dependentfiles[i]);
1488 if (len != buflen) {
1489 buf = (char *)Realloc(buf, len);
1496 kbuf.dsize = strlen(key)+1;
1500 ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
1503 DEBUG(0,("add_a_printer_driver_3: Adding driver with key %s failed.\n", key ));
1509 /****************************************************************************
1510 ****************************************************************************/
1511 static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
1513 NT_PRINTER_DRIVER_INFO_LEVEL_3 info3;
1516 info3.cversion = driver->version;
1517 fstrcpy(info3.name,driver->name);
1518 fstrcpy(info3.environment,driver->environment);
1519 fstrcpy(info3.driverpath,driver->driverpath);
1520 fstrcpy(info3.datafile,driver->datafile);
1521 fstrcpy(info3.configfile,driver->configfile);
1522 fstrcpy(info3.helpfile,driver->helpfile);
1523 fstrcpy(info3.monitorname,driver->monitorname);
1524 fstrcpy(info3.defaultdatatype,driver->defaultdatatype);
1525 info3.dependentfiles = driver->dependentfiles;
1527 return add_a_printer_driver_3(&info3);
1531 /****************************************************************************
1532 ****************************************************************************/
1533 static uint32 get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
1535 NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
1539 fstrcpy(info.name, in_prt);
1540 fstrcpy(info.defaultdatatype, "RAW");
1542 fstrcpy(info.driverpath, "");
1543 fstrcpy(info.datafile, "");
1544 fstrcpy(info.configfile, "");
1545 fstrcpy(info.helpfile, "");
1547 if ((info.dependentfiles=(fstring *)malloc(2*sizeof(fstring))) == NULL)
1548 return ERROR_NOT_ENOUGH_MEMORY;
1550 memset(info.dependentfiles, '\0', 2*sizeof(fstring));
1551 fstrcpy(info.dependentfiles[0], "");
1553 *info_ptr = memdup(&info, sizeof(info));
1558 /****************************************************************************
1559 ****************************************************************************/
1560 static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch, uint32 version)
1562 NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
1563 TDB_DATA kbuf, dbuf;
1564 fstring architecture;
1569 ZERO_STRUCT(driver);
1571 get_short_archi(architecture, in_arch);
1573 DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, in_prt));
1575 slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, in_prt);
1578 kbuf.dsize = strlen(key)+1;
1580 dbuf = tdb_fetch(tdb, kbuf);
1582 if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
1584 if (!dbuf.dptr) return 5;
1586 len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff",
1595 driver.defaultdatatype);
1598 while (len < dbuf.dsize) {
1599 driver.dependentfiles = (fstring *)Realloc(driver.dependentfiles,
1600 sizeof(fstring)*(i+2));
1601 if (driver.dependentfiles == NULL)
1604 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f",
1605 &driver.dependentfiles[i]);
1608 if (driver.dependentfiles != NULL)
1609 fstrcpy(driver.dependentfiles[i], "");
1611 safe_free(dbuf.dptr);
1613 if (len != dbuf.dsize) {
1614 if (driver.dependentfiles != NULL)
1615 safe_free(driver.dependentfiles);
1617 return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
1620 *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
1625 /****************************************************************************
1626 ****************************************************************************/
1627 uint32 get_a_printer_driver_9x_compatible(pstring line, fstring model)
1629 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1635 slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, "WIN40", 0, model);
1636 DEBUG(10,("driver key: [%s]\n", key));
1639 kbuf.dsize = strlen(key)+1;
1640 if (!tdb_exists(tdb, kbuf)) return False;
1643 get_a_printer_driver_3(&info3, model, "Windows 4.0", 0);
1645 DEBUGADD(10,("info3->name [%s]\n", info3->name));
1646 DEBUGADD(10,("info3->datafile [%s]\n", info3->datafile));
1647 DEBUGADD(10,("info3->helpfile [%s]\n", info3->helpfile));
1648 DEBUGADD(10,("info3->monitorname [%s]\n", info3->monitorname));
1649 DEBUGADD(10,("info3->defaultdatatype [%s]\n", info3->defaultdatatype));
1650 for (i=0; info3->dependentfiles && *info3->dependentfiles[i]; i++) {
1651 DEBUGADD(10,("info3->dependentfiles [%s]\n", info3->dependentfiles[i]));
1653 DEBUGADD(10,("info3->environment [%s]\n", info3->environment));
1654 DEBUGADD(10,("info3->driverpath [%s]\n", info3->driverpath));
1655 DEBUGADD(10,("info3->configfile [%s]\n", info3->configfile));
1657 /*pstrcat(line, info3->name); pstrcat(line, ":");*/
1658 trim_string(info3->configfile, "\\print$\\WIN40\\0\\", 0);
1659 pstrcat(line, info3->configfile);
1661 trim_string(info3->datafile, "\\print$\\WIN40\\0\\", 0);
1662 pstrcat(line, info3->datafile);
1664 trim_string(info3->helpfile, "\\print$\\WIN40\\0\\", 0);
1665 pstrcat(line, info3->helpfile);
1667 trim_string(info3->monitorname, "\\print$\\WIN40\\0\\", 0);
1668 pstrcat(line, info3->monitorname);
1670 pstrcat(line, "RAW"); /*info3->defaultdatatype);*/
1673 for (i=0; info3->dependentfiles &&
1674 *info3->dependentfiles[i]; i++) {
1675 if (i) pstrcat(line, ","); /* don't end in a "," */
1676 trim_string(info3->dependentfiles[i], "\\print$\\WIN40\\0\\", 0);
1677 pstrcat(line, info3->dependentfiles[i]);
1685 /****************************************************************************
1686 debugging function, dump at level 6 the struct in the logs
1687 ****************************************************************************/
1688 static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1691 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1694 DEBUG(106,("Dumping printer driver at level [%d]\n", level));
1700 if (driver.info_3 == NULL)
1703 info3=driver.info_3;
1705 DEBUGADD(106,("version:[%d]\n", info3->cversion));
1706 DEBUGADD(106,("name:[%s]\n", info3->name));
1707 DEBUGADD(106,("environment:[%s]\n", info3->environment));
1708 DEBUGADD(106,("driverpath:[%s]\n", info3->driverpath));
1709 DEBUGADD(106,("datafile:[%s]\n", info3->datafile));
1710 DEBUGADD(106,("configfile:[%s]\n", info3->configfile));
1711 DEBUGADD(106,("helpfile:[%s]\n", info3->helpfile));
1712 DEBUGADD(106,("monitorname:[%s]\n", info3->monitorname));
1713 DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
1715 for (i=0; info3->dependentfiles &&
1716 *info3->dependentfiles[i]; i++) {
1717 DEBUGADD(106,("dependentfile:[%s]\n",
1718 info3->dependentfiles[i]));
1725 DEBUGADD(1,("Level not implemented\n"));
1733 /****************************************************************************
1734 ****************************************************************************/
1735 static int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
1739 len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
1741 if (!nt_devmode) return len;
1743 len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
1744 nt_devmode->devicename,
1745 nt_devmode->formname,
1747 nt_devmode->specversion,
1748 nt_devmode->driverversion,
1750 nt_devmode->driverextra,
1751 nt_devmode->orientation,
1752 nt_devmode->papersize,
1753 nt_devmode->paperlength,
1754 nt_devmode->paperwidth,
1757 nt_devmode->defaultsource,
1758 nt_devmode->printquality,
1761 nt_devmode->yresolution,
1762 nt_devmode->ttoption,
1763 nt_devmode->collate,
1764 nt_devmode->logpixels,
1767 nt_devmode->bitsperpel,
1768 nt_devmode->pelswidth,
1769 nt_devmode->pelsheight,
1770 nt_devmode->displayflags,
1771 nt_devmode->displayfrequency,
1772 nt_devmode->icmmethod,
1773 nt_devmode->icmintent,
1774 nt_devmode->mediatype,
1775 nt_devmode->dithertype,
1776 nt_devmode->reserved1,
1777 nt_devmode->reserved2,
1778 nt_devmode->panningwidth,
1779 nt_devmode->panningheight,
1780 nt_devmode->private);
1783 if (nt_devmode->private) {
1784 len += tdb_pack(buf+len, buflen-len, "B",
1785 nt_devmode->driverextra,
1786 nt_devmode->private);
1789 DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname));
1794 /****************************************************************************
1795 ****************************************************************************/
1796 static int pack_specifics(NT_PRINTER_PARAM *param, char *buf, int buflen)
1800 while (param != NULL) {
1801 len += tdb_pack(buf+len, buflen-len, "pfdB",
1810 len += tdb_pack(buf+len, buflen-len, "p", param);
1816 /****************************************************************************
1817 delete a printer - this just deletes the printer info file, any open
1818 handles are not affected
1819 ****************************************************************************/
1820 uint32 del_a_printer(char *sharename)
1825 slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
1828 kbuf.dsize=strlen(key)+1;
1830 tdb_delete(tdb, kbuf);
1834 /* FIXME!!! Reorder so this forward declaration is not necessary --jerry */
1835 static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **, fstring);
1836 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **);
1837 /****************************************************************************
1838 ****************************************************************************/
1839 static uint32 update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
1843 int buflen, len, ret;
1844 TDB_DATA kbuf, dbuf;
1847 * in addprinter: no servername and the printer is the name
1848 * in setprinter: servername is \\server
1849 * and printer is \\server\\printer
1851 * Samba manages only local printers.
1852 * we currently don't support things like path=\\other_server\printer
1855 if (info->servername[0]!='\0') {
1856 trim_string(info->printername, info->servername, NULL);
1857 trim_string(info->printername, "\\", NULL);
1858 info->servername[0]='\0';
1862 * JFM: one day I'll forget.
1863 * below that's info->portname because that's the SAMBA sharename
1864 * and I made NT 'thinks' it's the portname
1865 * the info->sharename is the thing you can name when you add a printer
1866 * that's the short-name when you create shared printer for 95/98
1867 * So I've made a limitation in SAMBA: you can only have 1 printer model
1868 * behind a SAMBA share.
1876 len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffPfffff",
1879 info->default_priority,
1896 info->printprocessor,
1900 len += pack_devicemode(info->devmode, buf+len, buflen-len);
1902 len += pack_specifics(info->specific, buf+len, buflen-len);
1904 if (buflen != len) {
1905 buf = (char *)Realloc(buf, len);
1911 slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, info->sharename);
1914 kbuf.dsize = strlen(key)+1;
1918 ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
1921 DEBUG(8, ("error updating printer to tdb on disk\n"));
1925 DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n",
1926 info->sharename, info->drivername, info->portname, len));
1932 /****************************************************************************
1933 ****************************************************************************/
1934 void add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM **param)
1936 NT_PRINTER_PARAM *current;
1938 DEBUG(108,("add_a_specific_param\n"));
1940 (*param)->next=NULL;
1942 if (info_2->specific == NULL)
1944 info_2->specific=*param;
1948 current=info_2->specific;
1949 while (current->next != NULL) {
1950 current=current->next;
1952 current->next=*param;
1958 /****************************************************************************
1959 ****************************************************************************/
1960 BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
1962 NT_PRINTER_PARAM *current;
1963 NT_PRINTER_PARAM *previous;
1965 current=info_2->specific;
1968 if (current==NULL) return (False);
1970 if ( !strcmp(current->value, param->value) &&
1971 (strlen(current->value)==strlen(param->value)) ) {
1972 DEBUG(109,("deleting first value\n"));
1973 info_2->specific=current->next;
1974 safe_free(current->data);
1976 DEBUG(109,("deleted first value\n"));
1980 current=previous->next;
1982 while ( current!=NULL ) {
1983 if (!strcmp(current->value, param->value) &&
1984 strlen(current->value)==strlen(param->value) ) {
1985 DEBUG(109,("deleting current value\n"));
1986 previous->next=current->next;
1987 safe_free(current->data);
1989 DEBUG(109,("deleted current value\n"));
1993 previous=previous->next;
1994 current=current->next;
1999 /****************************************************************************
2000 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
2001 ****************************************************************************/
2002 void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr)
2004 NT_PRINTER_PARAM *param = *param_ptr;
2009 DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param->value));
2012 safe_free(param->data);
2018 /****************************************************************************
2019 Malloc and return an NT devicemode.
2020 ****************************************************************************/
2022 NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
2025 * should I init this ones ???
2026 nt_devmode->devicename
2030 NT_DEVICEMODE *nt_devmode = (NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE));
2032 if (nt_devmode == NULL) {
2033 DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
2037 ZERO_STRUCTP(nt_devmode);
2039 safe_strcpy(adevice, default_devicename, sizeof(adevice));
2040 fstrcpy(nt_devmode->devicename, adevice);
2042 fstrcpy(nt_devmode->formname, "Letter");
2044 nt_devmode->specversion = 0x0401;
2045 nt_devmode->driverversion = 0x0400;
2046 nt_devmode->size = 0x00DC;
2047 nt_devmode->driverextra = 0x0000;
2048 nt_devmode->fields = FORMNAME | TTOPTION | PRINTQUALITY |
2049 DEFAULTSOURCE | COPIES | SCALE |
2050 PAPERSIZE | ORIENTATION;
2051 nt_devmode->orientation = 1;
2052 nt_devmode->papersize = PAPER_LETTER;
2053 nt_devmode->paperlength = 0;
2054 nt_devmode->paperwidth = 0;
2055 nt_devmode->scale = 0x64;
2056 nt_devmode->copies = 01;
2057 nt_devmode->defaultsource = BIN_FORMSOURCE;
2058 nt_devmode->printquality = RES_HIGH; /* 0x0258 */
2059 nt_devmode->color = COLOR_MONOCHROME;
2060 nt_devmode->duplex = DUP_SIMPLEX;
2061 nt_devmode->yresolution = 0;
2062 nt_devmode->ttoption = TT_SUBDEV;
2063 nt_devmode->collate = COLLATE_FALSE;
2064 nt_devmode->icmmethod = 0;
2065 nt_devmode->icmintent = 0;
2066 nt_devmode->mediatype = 0;
2067 nt_devmode->dithertype = 0;
2069 /* non utilisés par un driver d'imprimante */
2070 nt_devmode->logpixels = 0;
2071 nt_devmode->bitsperpel = 0;
2072 nt_devmode->pelswidth = 0;
2073 nt_devmode->pelsheight = 0;
2074 nt_devmode->displayflags = 0;
2075 nt_devmode->displayfrequency = 0;
2076 nt_devmode->reserved1 = 0;
2077 nt_devmode->reserved2 = 0;
2078 nt_devmode->panningwidth = 0;
2079 nt_devmode->panningheight = 0;
2081 nt_devmode->private = NULL;
2085 /****************************************************************************
2086 Deepcopy an NT devicemode.
2087 ****************************************************************************/
2089 NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
2091 NT_DEVICEMODE *new_nt_devicemode = NULL;
2093 if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
2094 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
2098 new_nt_devicemode->private = NULL;
2099 if (nt_devicemode->private != NULL) {
2100 if ((new_nt_devicemode->private = memdup(nt_devicemode->private, nt_devicemode->driverextra)) == NULL) {
2101 safe_free(new_nt_devicemode);
2102 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
2107 return new_nt_devicemode;
2110 /****************************************************************************
2111 Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
2112 ****************************************************************************/
2114 void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
2116 NT_DEVICEMODE *nt_devmode = *devmode_ptr;
2118 if(nt_devmode == NULL)
2121 DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
2123 if(nt_devmode->private)
2124 safe_free(nt_devmode->private);
2126 safe_free(nt_devmode);
2127 *devmode_ptr = NULL;
2130 /****************************************************************************
2131 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
2132 ****************************************************************************/
2133 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
2135 NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
2136 NT_PRINTER_PARAM *param_ptr;
2141 DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
2143 free_nt_devicemode(&info->devmode);
2145 for(param_ptr = info->specific; param_ptr; ) {
2146 NT_PRINTER_PARAM *tofree = param_ptr;
2148 param_ptr = param_ptr->next;
2149 free_nt_printer_param(&tofree);
2152 safe_free(*info_ptr);
2157 /****************************************************************************
2158 ****************************************************************************/
2159 static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
2163 NT_DEVICEMODE devmode;
2165 ZERO_STRUCT(devmode);
2167 len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
2169 if (!*nt_devmode) return len;
2171 len += tdb_unpack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
2175 &devmode.specversion,
2176 &devmode.driverversion,
2178 &devmode.driverextra,
2179 &devmode.orientation,
2181 &devmode.paperlength,
2182 &devmode.paperwidth,
2185 &devmode.defaultsource,
2186 &devmode.printquality,
2189 &devmode.yresolution,
2195 &devmode.bitsperpel,
2197 &devmode.pelsheight,
2198 &devmode.displayflags,
2199 &devmode.displayfrequency,
2203 &devmode.dithertype,
2206 &devmode.panningwidth,
2207 &devmode.panningheight,
2210 if (devmode.private) {
2211 /* the len in tdb_unpack is an int value and
2212 * devmode.driverextra is only a short
2214 len += tdb_unpack(buf+len, buflen-len, "B", &extra_len, &devmode.private);
2215 devmode.driverextra=(uint16)extra_len;
2217 /* check to catch an invalid TDB entry so we don't segfault */
2218 if (devmode.driverextra == 0) {
2219 devmode.private = NULL;
2223 *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
2225 DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode.devicename, devmode.formname));
2226 if (devmode.private)
2227 DEBUG(8,("with a private section of %d bytes\n", devmode.driverextra));
2232 /****************************************************************************
2233 ****************************************************************************/
2234 static int unpack_specifics(NT_PRINTER_PARAM **list, char *buf, int buflen)
2237 NT_PRINTER_PARAM param, *p;
2242 len += tdb_unpack(buf+len, buflen-len, "p", &p);
2245 len += tdb_unpack(buf+len, buflen-len, "fdB",
2251 *list = memdup(¶m, sizeof(param));
2253 DEBUG(8,("specific: [%s], len: %d\n", param.value, param.data_len));
2259 static void map_to_os2_driver(fstring drivername)
2261 static BOOL initialised=False;
2262 static fstring last_from,last_to;
2263 char *mapfile = lp_os2_driver_map();
2264 char **lines = NULL;
2268 if (!strlen(drivername))
2275 *last_from = *last_to = 0;
2279 if (strequal(drivername,last_from)) {
2280 DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",drivername,last_to));
2281 fstrcpy(drivername,last_to);
2285 lines = file_lines_load(mapfile, &numlines);
2286 if (numlines == 0) {
2287 DEBUG(0,("No entries in OS/2 driver map %s\n",mapfile));
2291 DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile));
2293 for( i = 0; i < numlines; i++) {
2294 char *nt_name = lines[i];
2295 char *os2_name = strchr_m(nt_name,'=');
2302 while (isspace(*nt_name))
2305 if (!*nt_name || strchr_m("#;",*nt_name))
2309 int l = strlen(nt_name);
2310 while (l && isspace(nt_name[l-1])) {
2316 while (isspace(*os2_name))
2320 int l = strlen(os2_name);
2321 while (l && isspace(os2_name[l-1])) {
2327 if (strequal(nt_name,drivername)) {
2328 DEBUG(3,("Mapped windows driver %s to os2 driver%s\n",drivername,os2_name));
2329 fstrcpy(last_from,drivername);
2330 fstrcpy(last_to,os2_name);
2331 fstrcpy(drivername,os2_name);
2332 file_lines_free(lines);
2337 file_lines_free(lines);
2340 /****************************************************************************
2341 get a default printer info 2 struct
2342 ****************************************************************************/
2343 static uint32 get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
2345 extern pstring global_myname;
2347 NT_PRINTER_INFO_LEVEL_2 info;
2351 snum = lp_servicenumber(sharename);
2353 slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", global_myname);
2354 slprintf(info.printername, sizeof(info.printername)-1, "\\\\%s\\%s",
2355 global_myname, sharename);
2356 fstrcpy(info.sharename, sharename);
2357 fstrcpy(info.portname, SAMBA_PRINTER_PORT_NAME);
2358 fstrcpy(info.drivername, lp_printerdriver(snum));
2361 if (!*info.drivername)
2362 fstrcpy(info.drivername, "NO DRIVER AVAILABLE FOR THIS PRINTER");
2364 /* by setting the driver name to an empty string, a local NT admin
2365 can now run the **local** APW to install a local printer driver
2366 for a Samba shared printer in 2.2. Without this, drivers **must** be
2367 installed on the Samba server for NT clients --jerry */
2368 if (!*info.drivername)
2369 fstrcpy(info.drivername, "");
2373 DEBUG(10,("get_a_printer_2_default: driver name set to [%s]\n", info.drivername));
2375 pstrcpy(info.comment, "");
2376 fstrcpy(info.printprocessor, "winprint");
2377 fstrcpy(info.datatype, "RAW");
2379 info.attributes = PRINTER_ATTRIBUTE_SHARED \
2380 | PRINTER_ATTRIBUTE_LOCAL \
2381 | PRINTER_ATTRIBUTE_RAW_ONLY \
2382 | PRINTER_ATTRIBUTE_QUEUED ; /* attributes */
2384 info.starttime = 0; /* Minutes since 12:00am GMT */
2385 info.untiltime = 0; /* Minutes since 12:00am GMT */
2387 info.default_priority = 1;
2388 info.setuptime = (uint32)time(NULL);
2390 #if 1 /* JRA - NO NOT CHANGE ! */
2391 info.devmode = NULL;
2394 * We should not return a default devicemode, as this causes
2395 * Win2K to not send the correct one on PCL drivers. It needs to
2396 * see a null devicemode so it can then overwrite the devicemode
2397 * on OpenPrinterEx. Yes this *is* insane :-). JRA.
2399 if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
2403 /* This will get the current RPC talloc context, but we should be
2404 passing this as a parameter... fixme... JRA ! */
2406 if (!nt_printing_getsec(get_talloc_ctx(), sharename, &info.secdesc_buf))
2409 *info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
2411 DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
2420 free_nt_devicemode(&info.devmode);
2424 /****************************************************************************
2425 ****************************************************************************/
2426 static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
2429 NT_PRINTER_INFO_LEVEL_2 info;
2431 TDB_DATA kbuf, dbuf;
2432 fstring printername;
2436 slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
2439 kbuf.dsize = strlen(key)+1;
2441 dbuf = tdb_fetch(tdb, kbuf);
2443 return get_a_printer_2_default(info_ptr, sharename);
2445 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff",
2448 &info.default_priority,
2465 info.printprocessor,
2469 /* Samba has to have shared raw drivers. */
2470 info.attributes |= (PRINTER_ATTRIBUTE_SHARED|PRINTER_ATTRIBUTE_RAW_ONLY);
2472 /* Restore the stripped strings. */
2473 slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", global_myname);
2474 slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", global_myname,
2476 fstrcpy(info.printername, printername);
2478 len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
2479 len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
2481 /* This will get the current RPC talloc context, but we should be
2482 passing this as a parameter... fixme... JRA ! */
2484 nt_printing_getsec(get_talloc_ctx(), sharename, &info.secdesc_buf);
2486 /* Fix for OS/2 drivers. */
2488 if (get_remote_arch() == RA_OS2)
2489 map_to_os2_driver(info.drivername);
2491 safe_free(dbuf.dptr);
2492 *info_ptr=memdup(&info, sizeof(info));
2494 DEBUG(9,("Unpacked printer [%s] name [%s] running driver [%s]\n",
2495 sharename, info.printername, info.drivername));
2501 /****************************************************************************
2502 debugging function, dump at level 6 the struct in the logs
2503 ****************************************************************************/
2504 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2507 NT_PRINTER_INFO_LEVEL_2 *info2;
2509 DEBUG(106,("Dumping printer at level [%d]\n", level));
2515 if (printer.info_2 == NULL)
2519 info2=printer.info_2;
2521 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
2522 DEBUGADD(106,("priority:[%d]\n", info2->priority));
2523 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
2524 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
2525 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
2526 DEBUGADD(106,("status:[%d]\n", info2->status));
2527 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
2528 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
2529 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
2530 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
2531 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
2533 DEBUGADD(106,("servername:[%s]\n", info2->servername));
2534 DEBUGADD(106,("printername:[%s]\n", info2->printername));
2535 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
2536 DEBUGADD(106,("portname:[%s]\n", info2->portname));
2537 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
2538 DEBUGADD(106,("comment:[%s]\n", info2->comment));
2539 DEBUGADD(106,("location:[%s]\n", info2->location));
2540 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
2541 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
2542 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
2543 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
2549 DEBUGADD(1,("Level not implemented\n"));
2557 /****************************************************************************
2558 Get the parameters we can substitute in an NT print job.
2559 ****************************************************************************/
2561 void get_printer_subst_params(int snum, fstring *printername, fstring *sharename, fstring *portname)
2563 NT_PRINTER_INFO_LEVEL *printer = NULL;
2565 **printername = **sharename = **portname = '\0';
2567 if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
2570 fstrcpy(*printername, printer->info_2->printername);
2571 fstrcpy(*sharename, printer->info_2->sharename);
2572 fstrcpy(*portname, printer->info_2->portname);
2574 free_a_printer(&printer, 2);
2578 * The function below are the high level ones.
2579 * only those ones must be called from the spoolss code.
2583 /****************************************************************************
2584 Modify a printer. This is called from SETPRINTERDATA/DELETEPRINTERDATA.
2585 ****************************************************************************/
2587 uint32 mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2591 dump_a_printer(printer, level);
2597 printer.info_2->c_setprinter++;
2598 result=update_a_printer_2(printer.info_2);
2609 /****************************************************************************
2610 Add a printer. This is called from ADDPRINTER(EX) and also SETPRINTER.
2611 We split this out from mod_a_printer as it updates the id's and timestamps.
2612 ****************************************************************************/
2614 uint32 add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
2618 dump_a_printer(printer, level);
2625 * Update the changestamp.
2626 * Note we must *not* do this in mod_a_printer().
2629 time_t time_unix = time(NULL);
2630 unix_to_nt_time(&time_nt, time_unix);
2631 if (printer.info_2->changeid==time_nt.low)
2632 printer.info_2->changeid++;
2634 printer.info_2->changeid=time_nt.low;
2636 printer.info_2->c_setprinter++;
2638 result=update_a_printer_2(printer.info_2);
2649 /****************************************************************************
2650 Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
2651 ****************************************************************************/
2653 uint32 get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename)
2656 NT_PRINTER_INFO_LEVEL *printer = NULL;
2660 DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
2666 if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
2667 DEBUG(0,("get_a_printer: malloc fail.\n"));
2670 ZERO_STRUCTP(printer);
2671 result=get_a_printer_2(&printer->info_2, sharename);
2673 dump_a_printer(*printer, level);
2674 *pp_printer = printer;
2685 DEBUG(10,("get_a_printer: [%s] level %u returning %u\n", sharename, (unsigned int)level, (unsigned int)result));
2690 /****************************************************************************
2691 Deletes a NT_PRINTER_INFO_LEVEL struct.
2692 ****************************************************************************/
2694 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
2697 NT_PRINTER_INFO_LEVEL *printer = *pp_printer;
2699 DEBUG(104,("freeing a printer at level [%d]\n", level));
2701 if (printer == NULL)
2708 if (printer->info_2 != NULL)
2710 free_nt_printer_info_level_2(&printer->info_2);
2729 /****************************************************************************
2730 ****************************************************************************/
2731 uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
2734 DEBUG(104,("adding a printer at level [%d]\n", level));
2735 dump_a_printer_driver(driver, level);
2741 result=add_a_printer_driver_3(driver.info_3);
2747 result=add_a_printer_driver_6(driver.info_6);
2757 /****************************************************************************
2758 ****************************************************************************/
2759 uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
2760 fstring printername, fstring architecture, uint32 version)
2768 result=get_a_printer_driver_3(&driver->info_3, printername, architecture, version);
2777 dump_a_printer_driver(*driver, level);
2781 /****************************************************************************
2782 ****************************************************************************/
2783 uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
2791 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
2792 if (driver.info_3 != NULL)
2794 info3=driver.info_3;
2795 safe_free(info3->dependentfiles);
2796 ZERO_STRUCTP(info3);
2808 NT_PRINTER_DRIVER_INFO_LEVEL_6 *info6;
2809 if (driver.info_6 != NULL)
2811 info6=driver.info_6;
2812 safe_free(info6->dependentfiles);
2813 safe_free(info6->previousnames);
2814 ZERO_STRUCTP(info6);
2832 /****************************************************************************
2833 Determine whether or not a particular driver is currently assigned
2835 ****************************************************************************/
2836 BOOL printer_driver_in_use (char *arch, char *driver)
2838 TDB_DATA kbuf, newkey, dbuf;
2839 NT_PRINTER_INFO_LEVEL_2 info;
2845 DEBUG(5,("printer_driver_in_use: Beginning search through printers.tdb...\n"));
2847 /* loop through the printers.tdb and check for the drivername */
2848 for (kbuf = tdb_firstkey(tdb); kbuf.dptr;
2849 newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey)
2852 dbuf = tdb_fetch(tdb, kbuf);
2856 if (strncmp(kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) != 0)
2859 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddddddfffffPfffff",
2862 &info.default_priority,
2879 info.printprocessor,
2883 safe_free(dbuf.dptr);
2886 DEBUG (0,("printer_driver_in_use: tdb_unpack failed for printer %s\n",
2891 DEBUG (10,("printer_driver_in_use: Printer - %s (%s)\n",
2892 info.printername, info.drivername));
2894 if (strcmp(info.drivername, driver) == 0)
2896 DEBUG(5,("printer_driver_in_use: Printer %s using %s\n",
2897 info.printername, driver));
2901 DEBUG(5,("printer_driver_in_use: Completed search through printers.tdb...\n"));
2905 /* report that the driver is in use by default */
2909 /****************************************************************************
2910 Remove a printer driver from the TDB. This assumes that the the driver was
2911 previously looked up.
2912 ***************************************************************************/
2913 uint32 delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i)
2920 get_short_archi(arch, i->environment);
2921 slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX,
2922 arch, i->cversion, i->name);
2923 DEBUG(5,("delete_printer_driver: key = [%s]\n", key));
2926 kbuf.dsize=strlen(key)+1;
2928 if (tdb_delete(tdb, kbuf) == -1) {
2929 DEBUG (0,("delete_printer_driver: fail to delete %s!\n", key));
2930 return NT_STATUS_ACCESS_VIOLATION;
2933 DEBUG(5,("delete_printer_driver: [%s] driver delete successful.\n",
2936 return NT_STATUS_NO_PROBLEMO;
2938 /****************************************************************************
2939 ****************************************************************************/
2940 BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
2941 fstring value, uint8 **data, uint32 *type, uint32 *len)
2943 /* right now that's enough ! */
2944 NT_PRINTER_PARAM *param;
2947 param=printer.info_2->specific;
2949 while (param != NULL && i < param_index) {
2957 /* exited because it exist */
2959 StrnCpy(value, param->value, sizeof(fstring)-1);
2960 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
2963 ZERO_STRUCTP(*data);
2964 memcpy(*data, param->data, param->data_len);
2965 *len=param->data_len;
2969 /****************************************************************************
2970 ****************************************************************************/
2971 BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level,
2972 fstring value, uint8 **data, uint32 *type, uint32 *len)
2974 /* right now that's enough ! */
2975 NT_PRINTER_PARAM *param;
2977 DEBUG(10, ("get_specific_param\n"));
2979 param=printer.info_2->specific;
2981 while (param != NULL)
2983 #if 1 /* JRA - I think this should be case insensitive.... */
2984 if ( strequal(value, param->value)
2986 if ( !strcmp(value, param->value)
2988 && strlen(value)==strlen(param->value))
2996 DEBUGADD(10, ("get_specific_param: found one param\n"));
2997 /* exited because it exist */
3000 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
3003 memcpy(*data, param->data, param->data_len);
3004 *len=param->data_len;
3006 DEBUGADD(10, ("get_specific_param: exit true\n"));
3009 DEBUGADD(10, ("get_specific_param: exit false\n"));
3013 /****************************************************************************
3014 Store a security desc for a printer.
3015 ****************************************************************************/
3017 uint32 nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
3019 SEC_DESC_BUF *new_secdesc_ctr = NULL;
3020 SEC_DESC_BUF *old_secdesc_ctr = NULL;
3022 TALLOC_CTX *mem_ctx = NULL;
3026 mem_ctx = talloc_init();
3027 if (mem_ctx == NULL)
3030 /* The old owner and group sids of the security descriptor are not
3031 present when new ACEs are added or removed by changing printer
3032 permissions through NT. If they are NULL in the new security
3033 descriptor then copy them over from the old one. */
3035 if (!secdesc_ctr->sec->owner_sid || !secdesc_ctr->sec->grp_sid) {
3036 DOM_SID *owner_sid, *group_sid;
3037 SEC_ACL *dacl, *sacl;
3038 SEC_DESC *psd = NULL;
3041 nt_printing_getsec(mem_ctx, printername, &old_secdesc_ctr);
3043 /* Pick out correct owner and group sids */
3045 owner_sid = secdesc_ctr->sec->owner_sid ?
3046 secdesc_ctr->sec->owner_sid :
3047 old_secdesc_ctr->sec->owner_sid;
3049 group_sid = secdesc_ctr->sec->grp_sid ?
3050 secdesc_ctr->sec->grp_sid :
3051 old_secdesc_ctr->sec->grp_sid;
3053 dacl = secdesc_ctr->sec->dacl ?
3054 secdesc_ctr->sec->dacl :
3055 old_secdesc_ctr->sec->dacl;
3057 sacl = secdesc_ctr->sec->sacl ?
3058 secdesc_ctr->sec->sacl :
3059 old_secdesc_ctr->sec->sacl;
3061 /* Make a deep copy of the security descriptor */
3063 psd = make_sec_desc(mem_ctx, secdesc_ctr->sec->revision,
3064 owner_sid, group_sid,
3069 new_secdesc_ctr = make_sec_desc_buf(mem_ctx, size, psd);
3072 if (!new_secdesc_ctr) {
3073 new_secdesc_ctr = secdesc_ctr;
3076 /* Store the security descriptor in a tdb */
3078 prs_init(&ps, (uint32)sec_desc_size(new_secdesc_ctr->sec) +
3079 sizeof(SEC_DESC_BUF), mem_ctx, MARSHALL);
3081 if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr,
3083 status = ERROR_INVALID_FUNCTION;
3087 slprintf(key, sizeof(key)-1, "SECDESC/%s", printername);
3089 if (tdb_prs_store(tdb, key, &ps)==0) {
3092 DEBUG(1,("Failed to store secdesc for %s\n", printername));
3093 status = ERROR_INVALID_FUNCTION;
3096 /* Free malloc'ed memory */
3102 talloc_destroy(mem_ctx);
3106 /****************************************************************************
3107 Construct a default security descriptor buffer for a printer.
3108 ****************************************************************************/
3110 static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
3114 SEC_ACL *psa = NULL;
3115 SEC_DESC_BUF *sdb = NULL;
3116 SEC_DESC *psd = NULL;
3119 enum SID_NAME_USE name_type;
3121 /* Create an ACE where Everyone is allowed to print */
3123 init_sec_access(&sa, PRINTER_ACE_PRINT);
3124 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
3125 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
3127 /* Make the security descriptor owned by the Administrators group
3128 on the PDC of the domain. */
3130 if (winbind_lookup_name(lp_workgroup(), &owner_sid, &name_type)) {
3131 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
3135 /* Backup plan - make printer owned by admins or root.
3136 This should emulate a lanman printer as security
3137 settings can't be changed. */
3139 sid_peek_rid(&owner_sid, &owner_rid);
3141 if (owner_rid != BUILTIN_ALIAS_RID_PRINT_OPS &&
3142 owner_rid != BUILTIN_ALIAS_RID_ADMINS &&
3143 owner_rid != DOMAIN_USER_RID_ADMIN &&
3144 !lookup_name("root", &owner_sid, &name_type)) {
3145 sid_copy(&owner_sid, &global_sid_World);
3149 init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
3150 init_sec_ace(&ace[1], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
3151 sa, SEC_ACE_FLAG_OBJECT_INHERIT |
3152 SEC_ACE_FLAG_INHERIT_ONLY);
3154 init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
3155 init_sec_ace(&ace[2], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
3156 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
3158 /* The ACL revision number in rpc_secdesc.h differs from the one
3159 created by NT when setting ACE entries in printer
3160 descriptors. NT4 complains about the property being edited by a
3163 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) != NULL) {
3164 psd = make_sec_desc(ctx, SEC_DESC_REVISION,
3166 NULL, psa, &sd_size);
3170 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
3174 sdb = make_sec_desc_buf(ctx, sd_size, psd);
3176 DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
3177 (unsigned int)sd_size));
3182 /****************************************************************************
3183 Get a security desc for a printer.
3184 ****************************************************************************/
3186 BOOL nt_printing_getsec(TALLOC_CTX *ctx, char *printername, SEC_DESC_BUF **secdesc_ctr)
3192 if ((temp = strchr_m(printername + 2, '\\'))) {
3193 printername = temp + 1;
3196 /* Fetch security descriptor from tdb */
3198 slprintf(key, sizeof(key)-1, "SECDESC/%s", printername);
3200 if (tdb_prs_fetch(tdb, key, &ps, ctx)!=0 ||
3201 !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
3203 DEBUG(4,("using default secdesc for %s\n", printername));
3205 if (!(*secdesc_ctr = construct_default_printer_sdb(ctx))) {
3212 /* If security descriptor is owned by S-1-1-0 and winbindd is up,
3213 this security descriptor has been created when winbindd was
3214 down. Take ownership of security descriptor. */
3216 if (sid_equal((*secdesc_ctr)->sec->owner_sid, &global_sid_World)) {
3218 enum SID_NAME_USE name_type;
3220 /* Change sd owner to workgroup administrator */
3222 if (winbind_lookup_name(lp_workgroup(), &owner_sid,
3224 SEC_DESC_BUF *new_secdesc_ctr = NULL;
3225 SEC_DESC *psd = NULL;
3230 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
3232 psd = make_sec_desc(ctx, (*secdesc_ctr)->sec->revision,
3234 (*secdesc_ctr)->sec->grp_sid,
3235 (*secdesc_ctr)->sec->sacl,
3236 (*secdesc_ctr)->sec->dacl,
3239 new_secdesc_ctr = make_sec_desc_buf(ctx, size, psd);
3241 /* Swap with other one */
3243 *secdesc_ctr = new_secdesc_ctr;
3247 nt_printing_setsec(printername, *secdesc_ctr);
3251 if (DEBUGLEVEL >= 10) {
3252 SEC_ACL *the_acl = (*secdesc_ctr)->sec->dacl;
3255 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
3256 printername, the_acl->num_aces));
3258 for (i = 0; i < the_acl->num_aces; i++) {
3261 sid_to_string(sid_str, &the_acl->ace[i].sid);
3263 DEBUG(10, ("%s %d %d 0x%08x\n", sid_str,
3264 the_acl->ace[i].type, the_acl->ace[i].flags,
3265 the_acl->ace[i].info.mask));
3275 1: level not implemented
3276 2: file doesn't exist
3277 3: can't allocate memory
3278 4: can't free memory
3279 5: non existant struct
3283 A printer and a printer driver are 2 different things.
3284 NT manages them separatelly, Samba does the same.
3285 Why ? Simply because it's easier and it makes sense !
3287 Now explanation: You have 3 printers behind your samba server,
3288 2 of them are the same make and model (laser A and B). But laser B
3289 has an 3000 sheet feeder and laser A doesn't such an option.
3290 Your third printer is an old dot-matrix model for the accounting :-).
3292 If the /usr/local/samba/lib directory (default dir), you will have
3293 5 files to describe all of this.
3295 3 files for the printers (1 by printer):
3298 NTprinter_accounting
3299 2 files for the drivers (1 for the laser and 1 for the dot matrix)
3300 NTdriver_printer model X
3301 NTdriver_printer model Y
3303 jfm: I should use this comment for the text file to explain
3304 same thing for the forms BTW.
3305 Je devrais mettre mes commentaires en francais, ca serait mieux :-)
3309 /* Convert generic access rights to printer object specific access rights.
3310 It turns out that NT4 security descriptors use generic access rights and
3311 NT5 the object specific ones. */
3313 void map_printer_permissions(SEC_DESC *sd)
3317 for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
3318 se_map_generic(&sd->dacl->ace[i].info.mask,
3319 &printer_generic_mapping);
3323 /****************************************************************************
3324 Check a user has permissions to perform the given operation. We use the
3325 permission constants defined in include/rpc_spoolss.h to check the various
3326 actions we perform when checking printer access.
3328 PRINTER_ACCESS_ADMINISTER:
3329 print_queue_pause, print_queue_resume, update_printer_sec,
3330 update_printer, spoolss_addprinterex_level_2,
3331 _spoolss_setprinterdata
3336 JOB_ACCESS_ADMINISTER:
3337 print_job_delete, print_job_pause, print_job_resume,
3340 ****************************************************************************/
3341 BOOL print_access_check(struct current_user *user, int snum, int access_type)
3343 SEC_DESC_BUF *secdesc = NULL;
3344 uint32 access_granted, status;
3347 TALLOC_CTX *mem_ctx = NULL;
3348 extern struct current_user current_user;
3350 /* If user is NULL then use the current_user structure */
3352 if (!user) user = ¤t_user;
3354 /* Always allow root or printer admins to do anything */
3356 if (user->uid == 0 ||
3357 user_in_list(uidtoname(user->uid), lp_printer_admin(snum))) {
3361 /* Get printer name */
3363 pname = PRINTERNAME(snum);
3365 if (!pname || !*pname) {
3370 /* Get printer security descriptor */
3372 if(!(mem_ctx = talloc_init())) {
3377 nt_printing_getsec(mem_ctx, pname, &secdesc);
3379 if (access_type == JOB_ACCESS_ADMINISTER) {
3380 SEC_DESC_BUF *parent_secdesc = secdesc;
3382 /* Create a child security descriptor to check permissions
3383 against. This is because print jobs are child objects
3384 objects of a printer. */
3386 secdesc = se_create_child_secdesc(mem_ctx, parent_secdesc->sec, False);
3388 /* Now this is the bit that really confuses me. The access
3389 type needs to be changed from JOB_ACCESS_ADMINISTER to
3390 PRINTER_ACCESS_ADMINISTER for this to work. Something
3391 to do with the child (job) object becoming like a
3394 access_type = PRINTER_ACCESS_ADMINISTER;
3399 map_printer_permissions(secdesc->sec);
3401 result = se_access_check(secdesc->sec, user, access_type,
3402 &access_granted, &status);
3404 DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE"));
3406 talloc_destroy(mem_ctx);
3414 /****************************************************************************
3415 Check the time parameters allow a print operation.
3416 *****************************************************************************/
3418 BOOL print_time_access_check(int snum)
3420 NT_PRINTER_INFO_LEVEL *printer = NULL;
3422 time_t now = time(NULL);
3426 if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
3429 if (printer->info_2->starttime == 0 && printer->info_2->untiltime == 0)
3433 mins = (uint32)t->tm_hour*60 + (uint32)t->tm_min;
3435 if (mins >= printer->info_2->starttime && mins <= printer->info_2->untiltime)
3438 free_a_printer(&printer, 2);
3446 /****************************************************************************
3447 Attempt to write a default device.
3448 *****************************************************************************/
3450 uint32 printer_write_default_dev(int snum, const PRINTER_DEFAULT *printer_default)
3452 NT_PRINTER_INFO_LEVEL *printer = NULL;
3457 * Don't bother if no default devicemode was sent.
3460 if (printer_default->devmode_cont.devmode == NULL)
3463 if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
3464 return ERROR_ACCESS_DENIED;
3467 * Just ignore it if we already have a devmode.
3470 if (printer->info_2->devmode != NULL)
3474 * We don't have a devicemode and we're trying to write
3475 * one. Check we have the access needed.
3477 DEBUG(5,("printer_write_default_dev: access: %x\n", printer_default->access_required));
3479 if ( (printer_default->access_required & PRINTER_ACCESS_ADMINISTER) !=
3480 PRINTER_ACCESS_ADMINISTER) {
3481 DEBUG(5,("printer_write_default_dev: invalid request access to update: %x\n", printer_default->access_required));
3482 result = ERROR_ACCESS_DENIED;
3486 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
3487 DEBUG(5,("printer_write_default_dev: Access denied for printer %s\n",
3488 lp_servicename(snum) ));
3489 result = ERROR_ACCESS_DENIED;
3490 /*result = NT_STATUS_NO_PROBLEMO;*/
3494 DEBUG(5,("printer_write_default_dev: updating, check OK.\n"));
3497 * Convert the on the wire devicemode format to the internal one.
3500 if (!convert_devicemode(printer->info_2->printername,
3501 printer_default->devmode_cont.devmode,
3502 &printer->info_2->devmode)) {
3503 result = ERROR_NOT_ENOUGH_MEMORY;
3508 * Finally write back to the tdb.
3511 if (add_a_printer(*printer, 2)!=0) {
3512 result = ERROR_ACCESS_DENIED;
3518 free_a_printer(&printer, 2);