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