c70a6891d4794f39d779e4070417a188d5faf9ff
[nivanova/samba-autobuild/.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 /* We need one default form to support our default printer. Msoft adds the
39 forms it wants and in the ORDER it wants them (note: DEVMODE papersize is an
40 array index). Letter is always first, so (for the current code) additions
41 always put things in the correct order. */
42 static nt_forms_struct default_forms[] = {
43         {"Letter", 0x2, 0x34b5b, 0x44367, 0x0, 0x0, 0x34b5b, 0x44367},
44 };
45
46
47 /****************************************************************************
48 open the NT printing tdb
49 ****************************************************************************/
50 BOOL nt_printing_init(void)
51 {
52         static pid_t local_pid;
53         char *vstring = "INFO/version";
54
55         if (tdb && local_pid == sys_getpid()) return True;
56         tdb = tdb_open(lock_path("ntdrivers.tdb"), 0, 0, O_RDWR|O_CREAT, 0600);
57         if (!tdb) {
58                 DEBUG(0,("Failed to open nt drivers database\n"));
59                 return False;
60         }
61
62         local_pid = sys_getpid();
63
64         /* handle a Samba upgrade */
65         tdb_lock_bystring(tdb, vstring);
66         if (tdb_fetch_int(tdb, vstring) != DATABASE_VERSION) {
67                 tdb_traverse(tdb, (tdb_traverse_func)tdb_delete, NULL);
68                 tdb_store_int(tdb, vstring, DATABASE_VERSION);
69         }
70         tdb_unlock_bystring(tdb, vstring);
71
72         return True;
73 }
74
75   
76 /****************************************************************************
77 get a form struct list
78 ****************************************************************************/
79 int get_ntforms(nt_forms_struct **list)
80 {
81         TDB_DATA kbuf, newkey, dbuf;
82         nt_forms_struct form;
83         int ret;
84         int i;
85         int n = 0;
86
87         for (kbuf = tdb_firstkey(tdb); 
88              kbuf.dptr; 
89              newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
90                 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0) continue;
91                 
92                 dbuf = tdb_fetch(tdb, kbuf);
93                 if (!dbuf.dptr) continue;
94
95                 fstrcpy(form.name, kbuf.dptr+strlen(FORMS_PREFIX));
96                 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddd",
97                                  &i, &form.flag, &form.width, &form.length, &form.left,
98                                  &form.top, &form.right, &form.bottom);
99                 safe_free(dbuf.dptr);
100                 if (ret != dbuf.dsize) continue;
101
102                 /* allocate space and populate the list in correct order */
103                 if (i+1 > n) {
104                         *list = Realloc(*list, sizeof(nt_forms_struct)*(i+1));
105                         n = i+1;
106                 }
107                 (*list)[i] = form;
108         }
109
110         /* we should never return a null forms list or NT gets unhappy */
111         if (n == 0) {
112                 *list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));
113                 n = sizeof(default_forms) / sizeof(default_forms[0]);
114         }
115         
116
117         return n;
118 }
119
120 /****************************************************************************
121 write a form struct list
122 ****************************************************************************/
123 int write_ntforms(nt_forms_struct **list, int number)
124 {
125         pstring buf, key;
126         int len;
127         TDB_DATA kbuf,dbuf;
128         int i;
129
130         for (i=0;i<number;i++) {
131                 /* save index, so list is rebuilt in correct order */
132                 len = tdb_pack(buf, sizeof(buf), "dddddddd",
133                                i, (*list)[i].flag, (*list)[i].width, (*list)[i].length,
134                                (*list)[i].left, (*list)[i].top, (*list)[i].right, 
135                                (*list)[i].bottom);
136                 if (len > sizeof(buf)) break;
137                 slprintf(key, sizeof(key), "%s%s", FORMS_PREFIX, (*list)[i].name);
138                 kbuf.dsize = strlen(key)+1;
139                 kbuf.dptr = key;
140                 dbuf.dsize = len;
141                 dbuf.dptr = buf;
142                 if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) break;
143        }
144
145        return i;
146 }
147
148 /****************************************************************************
149 add a form struct at the end of the list
150 ****************************************************************************/
151 BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
152 {
153         int n=0;
154         BOOL update;
155         fstring form_name;
156
157         /* 
158          * NT tries to add forms even when 
159          * they are already in the base
160          * only update the values if already present
161          */
162
163         update=False;
164         
165         unistr2_to_ascii(form_name, &form->name, sizeof(form_name)-1);
166         for (n=0; n<*count && update==False; n++)
167         {
168                 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
169                 {
170                         DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
171                         update=True;
172                 }
173         }
174
175         if (update==False)
176         {
177                 if((*list=Realloc(*list, (n+1)*sizeof(nt_forms_struct))) == NULL)
178                         return False;
179                 unistr2_to_ascii((*list)[n].name, &form->name, sizeof((*list)[n].name)-1);
180                 (*count)++;
181         }
182         
183         (*list)[n].flag=form->flags;
184         (*list)[n].width=form->size_x;
185         (*list)[n].length=form->size_y;
186         (*list)[n].left=form->left;
187         (*list)[n].top=form->top;
188         (*list)[n].right=form->right;
189         (*list)[n].bottom=form->bottom;
190
191         return True;
192 }
193
194 /****************************************************************************
195  delete a named form struct 
196 ****************************************************************************/
197 BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, uint32 *ret)
198 {
199         pstring key;
200         TDB_DATA kbuf;
201         int n=0;
202         fstring form_name;
203
204         *ret = 0;
205
206         if (*count == 1) {
207                 /*
208                  * Don't delete the last form (no empty lists).
209                  * CHECKME ! Is this correct ? JRA.
210                  */
211                 *ret = ERROR_INVALID_PARAMETER;
212                 return False;
213         }
214
215         unistr2_to_ascii(form_name, del_name, sizeof(form_name)-1);
216
217         for (n=0; n<*count; n++) {
218                 if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
219                         DEBUG(103, ("delete_a_form, [%s] in list\n", form_name));
220                         break;
221                 }
222         }
223
224         if (n == *count) {
225                 DEBUG(10,("delete_a_form, [%s] not found\n", form_name));
226                 *ret = ERROR_INVALID_PARAMETER;
227                 return False;
228         }
229
230         slprintf(key, sizeof(key), "%s%s", FORMS_PREFIX, (*list)[n].name);
231         kbuf.dsize = strlen(key)+1;
232         kbuf.dptr = key;
233         if (tdb_delete(tdb, kbuf) != 0) {
234                 *ret = ERROR_NOT_ENOUGH_MEMORY;
235                 return False;
236         }
237
238         return True;
239 }
240
241 /****************************************************************************
242 update a form struct 
243 ****************************************************************************/
244 void update_a_form(nt_forms_struct **list, const FORM *form, int count)
245 {
246         int n=0;
247         fstring form_name;
248         unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
249
250         DEBUG(106, ("[%s]\n", form_name));
251         for (n=0; n<count; n++)
252         {
253                 DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
254                 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
255                         break;
256         }
257
258         if (n==count) return;
259
260         (*list)[n].flag=form->flags;
261         (*list)[n].width=form->size_x;
262         (*list)[n].length=form->size_y;
263         (*list)[n].left=form->left;
264         (*list)[n].top=form->top;
265         (*list)[n].right=form->right;
266         (*list)[n].bottom=form->bottom;
267 }
268  
269 /****************************************************************************
270 get the nt drivers list
271
272 traverse the database and look-up the matching names
273 ****************************************************************************/
274 int get_ntdrivers(fstring **list, char *architecture, uint32 version)
275 {
276         int total=0;
277         fstring short_archi;
278         pstring key;
279         TDB_DATA kbuf, newkey;
280
281         get_short_archi(short_archi, architecture);
282         slprintf(key, sizeof(key), "%s%s/%d/", DRIVERS_PREFIX, short_archi, version);
283
284         for (kbuf = tdb_firstkey(tdb); 
285              kbuf.dptr; 
286              newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
287                 if (strncmp(kbuf.dptr, key, strlen(key)) != 0) continue;
288                 
289                 if((*list = Realloc(*list, sizeof(fstring)*(total+1))) == NULL)
290                         return -1;
291
292                 fstrcpy((*list)[total], kbuf.dptr+strlen(key));
293                 total++;
294         }
295
296         return(total);
297 }
298
299 /****************************************************************************
300 function to do the mapping between the long architecture name and
301 the short one.
302 ****************************************************************************/
303 BOOL get_short_archi(char *short_archi, char *long_archi)
304 {
305         struct table {
306                 char *long_archi;
307                 char *short_archi;
308         };
309         
310         struct table archi_table[]=
311         {
312                 {"Windows 4.0",          "WIN40"    },
313                 {"Windows NT x86",       "W32X86"   },
314                 {"Windows NT R4000",     "W32MIPS"  },
315                 {"Windows NT Alpha_AXP", "W32ALPHA" },
316                 {"Windows NT PowerPC",   "W32PPC"   },
317                 {NULL,                   ""         }
318         };
319         
320         int i=-1;
321
322         DEBUG(107,("Getting architecture dependant directory\n"));
323         do {
324                 i++;
325         } while ( (archi_table[i].long_archi!=NULL ) && 
326                   StrCaseCmp(long_archi, archi_table[i].long_archi) );
327
328         if (archi_table[i].long_archi==NULL) {
329                 DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
330                 return FALSE;
331         }
332
333         StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
334
335         DEBUGADD(108,("index: [%d]\n", i));
336         DEBUGADD(108,("long architecture: [%s]\n", long_archi));
337         DEBUGADD(108,("short architecture: [%s]\n", short_archi));
338         
339         return TRUE;
340 }
341
342 /****************************************************************************
343 Determine the correct cVersion associated with an architecture and driver
344 ****************************************************************************/
345 static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in)
346 {
347         int  fd = -1;
348         int  service;
349         int  cversion;
350         ssize_t  byte_count;
351         char buf[PE_HEADER_SIZE];
352         pstring driverpath;
353
354         /* If architecture is Windows 95/98, the version is always 0. */
355         if (strcmp(architecture, "WIN40") == 0) {
356                 DEBUG(10,("get_correct_cversion: Driver is Win9x, cversion = 0\n"));
357                 return 0;
358         }
359         
360         /* Open the driver file (Portable Executable format) and determine the
361          * deriver the cversion.
362          */
363         if ((service = find_service("print$")) == -1) {
364                 DEBUG(3,("get_correct_cversion: Can't find print$ service\n"));
365                 goto error_exit;
366         }
367
368         slprintf(driverpath, sizeof(driverpath), "%s/%s/%s",
369                          lp_pathname(service), architecture, driverpath_in);
370
371         dos_to_unix(driverpath, True);
372
373         if ((fd = sys_open(driverpath, O_RDONLY, 0)) == -1) {
374                 DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
375                                 driverpath, errno));
376                 goto error_exit;
377         }
378          
379         if ((byte_count = read(fd, buf, DOS_HEADER_SIZE)) < DOS_HEADER_SIZE) {
380                 DEBUG(3,("get_correct_cversion: File [%s] DOS header too short, bytes read = %d\n",
381                                 driverpath, byte_count));
382                 goto error_exit;
383         }
384
385         /* Is this really a DOS header? */
386         if (SVAL(buf,DOS_HEADER_MAGIC_OFFSET) != DOS_HEADER_MAGIC) {
387                 DEBUG(6,("get_correct_cversion: File [%s] bad DOS magic = 0x%x\n",
388                                 driverpath, SVAL(buf,DOS_HEADER_MAGIC_OFFSET)));
389                 goto error_exit;
390         }
391
392         /* Skip OEM header (if any) and the DOS stub to start of Windows header */
393         if (sys_lseek(fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
394                 DEBUG(3,("get_correct_cversion: File [%s] too short, errno = %d\n",
395                                 driverpath, errno));
396                 goto error_exit;
397         }
398
399         if ((byte_count = read(fd, buf, PE_HEADER_SIZE)) < PE_HEADER_SIZE) {
400                 DEBUG(3,("get_correct_cversion: File [%s] Windows header too short, bytes read = %d\n",
401                                 driverpath, byte_count));
402                 goto error_exit;
403         }
404         close(fd);
405
406         /* The header may be a PE (Portable Executable) or an NE (New Executable) */
407         if (IVAL(buf,PE_HEADER_SIGNATURE_OFFSET) == PE_HEADER_SIGNATURE) {
408                 if (SVAL(buf,PE_HEADER_MACHINE_OFFSET) == PE_HEADER_MACHINE_I386) {
409
410                         switch (SVAL(buf,PE_HEADER_MAJOR_OS_VER_OFFSET)) {
411                                 case 4: cversion = 2; break;    /* Win NT 4 */
412                                 case 5: cversion = 3; break;    /* Win 2000 */
413                                 default:
414                                         DEBUG(6,("get_correct_cversion: PE formated file [%s] bad version = %d\n",
415                                                         driverpath, SVAL(buf,PE_HEADER_MAJOR_OS_VER_OFFSET)));
416                                         goto error_exit;
417                         }
418                 } else {
419                         DEBUG(6,("get_correct_cversion: PE formatted file [%s] wrong machine = 0x%x\n",
420                                         driverpath, SVAL(buf,PE_HEADER_MACHINE_OFFSET)));
421                         goto error_exit;
422                 }
423
424         } else if (SVAL(buf,NE_HEADER_SIGNATURE_OFFSET) == NE_HEADER_SIGNATURE) {
425                 if (CVAL(buf,NE_HEADER_TARGET_OS_OFFSET) == NE_HEADER_TARGOS_WIN ) {
426
427                         switch (CVAL(buf,NE_HEADER_MAJOR_VER_OFFSET)) {
428                                 case 3: cversion = 0; break;    /* Win 3.x / Win 9x / Win ME */
429                         /*      case ?: cversion = 1; break;*/  /* Win NT 3.51 ... needs research JRR */
430                                 default:
431                                         DEBUG(6,("get_correct_cversion: NE formated file [%s] bad version = %d\n",
432                                                         driverpath, CVAL(buf,NE_HEADER_MAJOR_VER_OFFSET)));
433                                         goto error_exit;
434                         }
435                 } else {
436                         DEBUG(6,("get_correct_cversion: NE formatted file [%s] wrong target OS = 0x%x\n",
437                                         driverpath, CVAL(buf,NE_HEADER_TARGET_OS_OFFSET)));
438                         goto error_exit;
439                 }
440
441         } else {
442                 DEBUG(6,("get_correct_cversion: Unknown file format [%s], signature = 0x%x\n",
443                                 driverpath, IVAL(buf,PE_HEADER_SIGNATURE_OFFSET)));
444                 goto error_exit;
445         }
446
447         DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
448                         driverpath, cversion));
449         return cversion;
450
451
452         error_exit:
453                 if(fd != -1)
454                         close(fd);
455                 return -1;
456 }
457
458 /****************************************************************************
459 ****************************************************************************/
460 static uint32 clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
461 {
462         fstring architecture;
463         fstring new_name;
464         char *p;
465         int i;
466
467         /* clean up the driver name.
468          * we can get .\driver.dll
469          * or worse c:\windows\system\driver.dll !
470          */
471         /* using an intermediate string to not have overlaping memcpy()'s */
472         if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
473                 fstrcpy(new_name, p+1);
474                 fstrcpy(driver->driverpath, new_name);
475         }
476
477         if ((p = strrchr(driver->datafile,'\\')) != NULL) {
478                 fstrcpy(new_name, p+1);
479                 fstrcpy(driver->datafile, new_name);
480         }
481
482         if ((p = strrchr(driver->configfile,'\\')) != NULL) {
483                 fstrcpy(new_name, p+1);
484                 fstrcpy(driver->configfile, new_name);
485         }
486
487         if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
488                 fstrcpy(new_name, p+1);
489                 fstrcpy(driver->helpfile, new_name);
490         }
491
492         if (driver->dependentfiles) {
493                 for (i=0; *driver->dependentfiles[i]; i++) {
494                         if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
495                                 fstrcpy(new_name, p+1);
496                                 fstrcpy(driver->dependentfiles[i], new_name);
497                         }
498                 }
499         }
500
501         get_short_archi(architecture, driver->environment);
502         
503         /* jfm:7/16/2000 the client always sends the cversion=0.
504          * The server should check which version the driver is by reading
505          * the PE header of driver->driverpath.
506          *
507          * For Windows 95/98 the version is 0 (so the value sent is correct)
508          * For Windows NT (the architecture doesn't matter)
509          *      NT 3.1: cversion=0
510          *      NT 3.5/3.51: cversion=1
511          *      NT 4: cversion=2
512          *      NT2K: cversion=3
513          */
514         if ((driver->cversion = get_correct_cversion(architecture,
515                                                                                         driver->driverpath)) == -1)
516                 return NT_STATUS_FILE_INVALID;     /* Not the best error. Fix JRR */
517
518         return NT_STATUS_NO_PROBLEMO;
519 }
520          
521 /****************************************************************************
522 ****************************************************************************/
523 static uint32 clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
524 {
525         fstring architecture;
526         fstring new_name;
527         char *p;
528         int i;
529
530         /* clean up the driver name.
531          * we can get .\driver.dll
532          * or worse c:\windows\system\driver.dll !
533          */
534         /* using an intermediate string to not have overlaping memcpy()'s */
535         if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
536                 fstrcpy(new_name, p+1);
537                 fstrcpy(driver->driverpath, new_name);
538         }
539
540         if ((p = strrchr(driver->datafile,'\\')) != NULL) {
541                 fstrcpy(new_name, p+1);
542                 fstrcpy(driver->datafile, new_name);
543         }
544
545         if ((p = strrchr(driver->configfile,'\\')) != NULL) {
546                 fstrcpy(new_name, p+1);
547                 fstrcpy(driver->configfile, new_name);
548         }
549
550         if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
551                 fstrcpy(new_name, p+1);
552                 fstrcpy(driver->helpfile, new_name);
553         }
554
555         if (driver->dependentfiles) {
556                 for (i=0; *driver->dependentfiles[i]; i++) {
557                         if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
558                                 fstrcpy(new_name, p+1);
559                                 fstrcpy(driver->dependentfiles[i], new_name);
560                         }
561                 }
562         }
563
564         get_short_archi(architecture, driver->environment);
565
566         /* jfm:7/16/2000 the client always sends the cversion=0.
567          * The server should check which version the driver is by reading
568          * the PE header of driver->driverpath.
569          *
570          * For Windows 95/98 the version is 0 (so the value sent is correct)
571          * For Windows NT (the architecture doesn't matter)
572          *      NT 3.1: cversion=0
573          *      NT 3.5/3.51: cversion=1
574          *      NT 4: cversion=2
575          *      NT2K: cversion=3
576          */
577         if ((driver->version = get_correct_cversion(architecture,
578                                                                                         driver->driverpath)) == -1)
579                 return NT_STATUS_FILE_INVALID;     /* Not the best error. Fix JRR */
580
581         return NT_STATUS_NO_PROBLEMO;
582 }
583
584 /****************************************************************************
585 ****************************************************************************/
586 uint32 clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level)
587 {
588         switch (level) {
589                 case 3:
590                 {
591                         NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
592                         driver=driver_abstract.info_3;
593                         return clean_up_driver_struct_level_3(driver);
594                         break;
595                 }
596                 case 6:
597                 {
598                         NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver;
599                         driver=driver_abstract.info_6;
600                         return clean_up_driver_struct_level_6(driver);
601                         break;
602                 }
603                 default:
604                         return ERROR_INVALID_PARAMETER;
605         }
606 }
607
608 /****************************************************************************
609  This function sucks and should be replaced. JRA.
610 ****************************************************************************/
611
612 static void convert_level_6_to_level3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dst, NT_PRINTER_DRIVER_INFO_LEVEL_6 *src)
613 {
614     dst->cversion  = src->version;
615
616     fstrcpy( dst->name, src->name);
617     fstrcpy( dst->environment, src->environment);
618     fstrcpy( dst->driverpath, src->driverpath);
619     fstrcpy( dst->datafile, src->datafile);
620     fstrcpy( dst->configfile, src->configfile);
621     fstrcpy( dst->helpfile, src->helpfile);
622     fstrcpy( dst->monitorname, src->monitorname);
623     fstrcpy( dst->defaultdatatype, src->defaultdatatype);
624     dst->dependentfiles = src->dependentfiles;
625 }
626
627
628 /****************************************************************************
629 ****************************************************************************/
630 BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level, struct current_user *user, uint32 *perr)
631 {
632         NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
633         NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver;
634         fstring architecture;
635         pstring new_dir;
636         pstring old_name;
637         pstring new_name;
638         fstring user_name;
639         fstring null_pw;
640         connection_struct *conn;
641         pstring inbuf;
642         pstring outbuf;
643         struct smb_passwd *smb_pass;
644         int ecode;
645         int outsize = 0;
646         int i;
647
648         *perr = 0;
649         memset(inbuf, '\0', sizeof(inbuf));
650         memset(outbuf, '\0', sizeof(outbuf));
651
652         if (level==3)
653                 driver=driver_abstract.info_3;
654         else if (level==6) {
655                 convert_level_6_to_level3(&converted_driver, driver_abstract.info_6);
656                 driver = &converted_driver;
657         } else {
658                 DEBUG(0,("move_driver_to_download_area: Unknown info level (%u)\n", (unsigned int)level ));
659                 return False;
660         }
661
662         get_short_archi(architecture, driver->environment);
663
664         become_root();
665         smb_pass = getsmbpwuid(user->uid);
666         if(smb_pass == NULL) {
667                 DEBUG(0,("move_driver_to_download_area: Unable to get smbpasswd entry for uid %u\n",
668                                 (unsigned int)user->uid ));
669                 unbecome_root();
670                 return False;
671         }
672         unbecome_root();
673
674         /* connect to the print$ share under the same account as the user connected to the rpc pipe */  
675         fstrcpy(user_name, smb_pass->smb_name );
676         DEBUG(10,("move_driver_to_download_area: uid %d -> user %s\n", (int)user->uid, user_name));
677
678         /* Null password is ok - we are already an authenticated user... */
679         *null_pw = '\0';
680         conn = make_connection("print$", user_name, null_pw, 0, "A:", user->vuid, &ecode);
681
682         if (conn == NULL) {
683                 DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
684                 *perr = (uint32)ecode;
685                 return False;
686         }
687
688         /*
689          * Save who we are - we are temporarily becoming the connection user.
690          */
691
692         push_sec_ctx();
693
694         if (!become_user(conn, conn->vuid)) {
695                 DEBUG(0,("move_driver_to_download_area: Can't become user %s\n", user_name ));
696                 pop_sec_ctx();
697                 return False;
698         }
699
700         /* 
701          * make the directories version and version\driver_name 
702          * under the architecture directory.
703          */
704         DEBUG(5,("Creating first directory\n"));
705         slprintf(new_dir, sizeof(new_dir), "%s\\%d", architecture, driver->cversion);
706         mkdir_internal(conn, inbuf, outbuf, new_dir);
707
708         /* move all the files, one by one, 
709          * from archi\filexxx.yyy to
710          * archi\version\filexxx.yyy
711          *
712          * Note: drivers may list the same file name in several places. This
713          * causes problems on a second attempt to move the file. JRR
714          *
715          * Note: use the replace flag on rename_internals() call, otherwise it
716          * is very difficult to change previously installed drivers... the Windows
717          * GUI offers the user the choice to replace or keep exisitng driver. JRR
718          */
719
720         DEBUG(5,("Moving file now !\n"));
721
722         if (driver->driverpath && strlen(driver->driverpath)) {
723         slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->driverpath);       
724         slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->driverpath);    
725         if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
726                 DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
727                                 old_name, new_name ));
728                 close_cnum(conn, user->vuid);
729                 pop_sec_ctx();
730                 *perr = (uint32)SVAL(outbuf,smb_err);
731                 return False;
732         }
733         }
734
735         if (driver->datafile && strlen(driver->datafile)) {
736         if (!strequal(driver->datafile, driver->driverpath)) {
737                 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->datafile); 
738                 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->datafile);      
739                 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
740                         DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
741                                         old_name, new_name ));
742                         close_cnum(conn, user->vuid);
743                         pop_sec_ctx();
744                         *perr = (uint32)SVAL(outbuf,smb_err);
745                         return False;
746                 }
747         }
748         }
749
750         if (driver->configfile && strlen(driver->configfile)) {
751         if (!strequal(driver->configfile, driver->driverpath) &&
752                 !strequal(driver->configfile, driver->datafile)) {
753                 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->configfile);       
754                 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->configfile);    
755                 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
756                         DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
757                                 old_name, new_name ));
758                         close_cnum(conn, user->vuid);
759                         pop_sec_ctx();
760                         *perr = (uint32)SVAL(outbuf,smb_err);
761                         return False;
762                 }
763         }
764         }
765
766         if (driver->helpfile && strlen(driver->helpfile)) {
767         if (!strequal(driver->helpfile, driver->driverpath) &&
768                         !strequal(driver->helpfile, driver->datafile) &&
769                         !strequal(driver->helpfile, driver->configfile)) {
770                 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->helpfile); 
771                 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->helpfile);      
772                 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
773                         DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
774                                 old_name, new_name ));
775                         close_cnum(conn, user->vuid);
776                         pop_sec_ctx();
777                         *perr = (uint32)SVAL(outbuf,smb_err);
778                         return False;
779                 }
780         }
781         }
782
783         if (driver->dependentfiles) {
784                 for (i=0; *driver->dependentfiles[i]; i++) {
785                         if (!strequal(driver->dependentfiles[i], driver->driverpath) &&
786                                         !strequal(driver->dependentfiles[i], driver->datafile) &&
787                                         !strequal(driver->dependentfiles[i], driver->configfile) &&
788                                         !strequal(driver->dependentfiles[i], driver->helpfile)) {
789                                 int j;
790                                 for (j=0; j < i; j++) {
791                                         if (strequal(driver->dependentfiles[i], driver->dependentfiles[j])) {
792                                                 goto NextDriver;
793                                         }
794                                 }
795
796                                 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->dependentfiles[i]);        
797                                 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->dependentfiles[i]);     
798                                 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
799                                         DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
800                                                 old_name, new_name ));
801                                         close_cnum(conn, user->vuid);
802                                         pop_sec_ctx();
803                                         *perr = (uint32)SVAL(outbuf,smb_err);
804                                         return False;
805                                 }
806                         }
807                 NextDriver: ;
808                 }
809         }
810
811         close_cnum(conn, user->vuid);
812         pop_sec_ctx();
813
814         return True;
815 }
816
817 /****************************************************************************
818 ****************************************************************************/
819 static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
820 {
821         int len, buflen;
822         fstring architecture;
823         pstring directory;
824         pstring temp_name;
825         pstring key;
826         char *buf;
827         int i, ret;
828         TDB_DATA kbuf, dbuf;
829
830         get_short_archi(architecture, driver->environment);
831
832         /* The names are relative. We store them in the form: \print$\arch\version\driver.xxx
833          * \\server is added in the rpc server layer.
834          * It does make sense to NOT store the server's name in the printer TDB.
835          */
836
837         slprintf(directory, sizeof(directory), "\\print$\\%s\\%d\\", architecture, driver->cversion);
838
839         
840         fstrcpy(temp_name, driver->driverpath);
841         slprintf(driver->driverpath, sizeof(driver->driverpath), "%s%s", directory, temp_name);
842
843         fstrcpy(temp_name, driver->datafile);
844         slprintf(driver->datafile, sizeof(driver->datafile), "%s%s", directory, temp_name);
845
846         fstrcpy(temp_name, driver->configfile);
847         slprintf(driver->configfile, sizeof(driver->configfile), "%s%s", directory, temp_name);
848
849         fstrcpy(temp_name, driver->helpfile);
850         slprintf(driver->helpfile, sizeof(driver->helpfile), "%s%s", directory, temp_name);
851
852         if (driver->dependentfiles) {
853                 for (i=0; *driver->dependentfiles[i]; i++) {
854                         fstrcpy(temp_name, driver->dependentfiles[i]);
855                         slprintf(driver->dependentfiles[i], sizeof(driver->dependentfiles[i]), "%s%s", directory, temp_name);
856                 }
857         }
858
859         slprintf(key, sizeof(key), "%s%s/%d/%s", DRIVERS_PREFIX, architecture, driver->cversion, driver->name);
860
861         DEBUG(5,("add_a_printer_driver_3: Adding driver with key %s\n", key ));
862
863         buf = NULL;
864         len = buflen = 0;
865
866  again:
867         len = 0;
868         len += tdb_pack(buf+len, buflen-len, "dffffffff", 
869                         driver->cversion,
870                         driver->name,
871                         driver->environment,
872                         driver->driverpath,
873                         driver->datafile,
874                         driver->configfile,
875                         driver->helpfile,
876                         driver->monitorname,
877                         driver->defaultdatatype);
878
879         if (driver->dependentfiles) {
880                 for (i=0; *driver->dependentfiles[i]; i++) {
881                         len += tdb_pack(buf+len, buflen-len, "f", 
882                                         driver->dependentfiles[i]);
883                 }
884         }
885
886         if (len != buflen) {
887                 buf = (char *)Realloc(buf, len);
888                 buflen = len;
889                 goto again;
890         }
891
892
893         kbuf.dptr = key;
894         kbuf.dsize = strlen(key)+1;
895         dbuf.dptr = buf;
896         dbuf.dsize = len;
897         
898         ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
899
900         if (ret)
901                 DEBUG(0,("add_a_printer_driver_3: Adding driver with key %s failed.\n", key ));
902
903         safe_free(buf);
904         return ret;
905 }
906
907 /****************************************************************************
908 ****************************************************************************/
909 static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
910 {
911         NT_PRINTER_DRIVER_INFO_LEVEL_3 info3;
912
913         ZERO_STRUCT(info3);
914         info3.cversion = driver->version;
915         fstrcpy(info3.name,driver->name);
916         fstrcpy(info3.environment,driver->environment);
917         fstrcpy(info3.driverpath,driver->driverpath);
918         fstrcpy(info3.datafile,driver->datafile);
919         fstrcpy(info3.configfile,driver->configfile);
920         fstrcpy(info3.helpfile,driver->helpfile);
921         fstrcpy(info3.monitorname,driver->monitorname);
922         fstrcpy(info3.defaultdatatype,driver->defaultdatatype);
923         info3.dependentfiles = driver->dependentfiles;
924
925         return add_a_printer_driver_3(&info3);
926 }
927
928
929 /****************************************************************************
930 ****************************************************************************/
931 static uint32 get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
932 {
933         NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
934
935         ZERO_STRUCT(info);
936
937         fstrcpy(info.name, in_prt);
938         fstrcpy(info.defaultdatatype, "RAW");
939         
940         fstrcpy(info.driverpath, "");
941         fstrcpy(info.datafile, "");
942         fstrcpy(info.configfile, "");
943         fstrcpy(info.helpfile, "");
944
945         if ((info.dependentfiles=(fstring *)malloc(2*sizeof(fstring))) == NULL)
946                 return ERROR_NOT_ENOUGH_MEMORY;
947
948         memset(info.dependentfiles, '\0', 2*sizeof(fstring));
949         fstrcpy(info.dependentfiles[0], "");
950
951         *info_ptr = memdup(&info, sizeof(info));
952         
953         return 0;       
954 }
955
956 /****************************************************************************
957 ****************************************************************************/
958 static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch, uint32 version)
959 {
960         NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
961         TDB_DATA kbuf, dbuf;
962         fstring architecture;
963         int len = 0;
964         int i;
965         pstring key;
966
967         ZERO_STRUCT(driver);
968
969         get_short_archi(architecture, in_arch);
970
971         DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, in_prt));
972
973         slprintf(key, sizeof(key), "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, in_prt);
974
975         kbuf.dptr = key;
976         kbuf.dsize = strlen(key)+1;
977         
978         dbuf = tdb_fetch(tdb, kbuf);
979 #if 0
980         if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
981 #else
982         if (!dbuf.dptr) return 5;
983 #endif
984         len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff", 
985                           &driver.cversion,
986                           driver.name,
987                           driver.environment,
988                           driver.driverpath,
989                           driver.datafile,
990                           driver.configfile,
991                           driver.helpfile,
992                           driver.monitorname,
993                           driver.defaultdatatype);
994
995         i=0;
996         while (len < dbuf.dsize) {
997                 driver.dependentfiles = (fstring *)Realloc(driver.dependentfiles,
998                                                          sizeof(fstring)*(i+2));
999                 if (driver.dependentfiles == NULL)
1000                         break;
1001
1002                 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f", 
1003                                   &driver.dependentfiles[i]);
1004                 i++;
1005         }
1006         if (driver.dependentfiles != NULL)
1007                 fstrcpy(driver.dependentfiles[i], "");
1008
1009         safe_free(dbuf.dptr);
1010
1011         if (len != dbuf.dsize) {
1012                 if (driver.dependentfiles != NULL)
1013                         safe_free(driver.dependentfiles);
1014
1015                 return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
1016         }
1017
1018         *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
1019
1020         return 0;
1021 }
1022
1023 /****************************************************************************
1024 ****************************************************************************/
1025 uint32 get_a_printer_driver_9x_compatible(pstring line, fstring model)
1026 {
1027         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1028         TDB_DATA kbuf;
1029         pstring key;
1030         int i;
1031         line[0] = '\0';
1032
1033         slprintf(key, sizeof(key), "%s%s/%d/%s", DRIVERS_PREFIX, "WIN40", 0, model);
1034         DEBUG(10,("driver key: [%s]\n", key));
1035         
1036         kbuf.dptr = key;
1037         kbuf.dsize = strlen(key)+1;
1038         if (!tdb_exists(tdb, kbuf)) return False;
1039
1040         ZERO_STRUCT(info3);
1041         get_a_printer_driver_3(&info3, model, "Windows 4.0", 0);
1042         
1043     DEBUGADD(10,("info3->name            [%s]\n", info3->name));
1044     DEBUGADD(10,("info3->datafile        [%s]\n", info3->datafile));
1045     DEBUGADD(10,("info3->helpfile        [%s]\n", info3->helpfile));
1046     DEBUGADD(10,("info3->monitorname     [%s]\n", info3->monitorname));
1047     DEBUGADD(10,("info3->defaultdatatype [%s]\n", info3->defaultdatatype));
1048         for (i=0; info3->dependentfiles && *info3->dependentfiles[i]; i++) {
1049     DEBUGADD(10,("info3->dependentfiles  [%s]\n", info3->dependentfiles[i]));
1050     }
1051     DEBUGADD(10,("info3->environment     [%s]\n", info3->environment));
1052     DEBUGADD(10,("info3->driverpath      [%s]\n", info3->driverpath));
1053     DEBUGADD(10,("info3->configfile      [%s]\n", info3->configfile));
1054
1055         /*pstrcat(line, info3->name);             pstrcat(line, ":");*/
1056         trim_string(info3->configfile, "\\print$\\WIN40\\0\\", 0);
1057         pstrcat(line, info3->configfile);
1058     pstrcat(line, ":");
1059         trim_string(info3->datafile, "\\print$\\WIN40\\0\\", 0);
1060         pstrcat(line, info3->datafile);
1061     pstrcat(line, ":");
1062         trim_string(info3->helpfile, "\\print$\\WIN40\\0\\", 0);
1063         pstrcat(line, info3->helpfile);
1064     pstrcat(line, ":");
1065         trim_string(info3->monitorname, "\\print$\\WIN40\\0\\", 0);
1066         pstrcat(line, info3->monitorname);
1067     pstrcat(line, ":");
1068         pstrcat(line, "RAW");                /*info3->defaultdatatype);*/
1069     pstrcat(line, ":");
1070
1071         for (i=0; info3->dependentfiles &&
1072                  *info3->dependentfiles[i]; i++) {
1073                 if (i) pstrcat(line, ",");               /* don't end in a "," */
1074                 trim_string(info3->dependentfiles[i], "\\print$\\WIN40\\0\\", 0);
1075                 pstrcat(line, info3->dependentfiles[i]);
1076         }
1077         
1078         free(info3);
1079
1080         return True;    
1081 }
1082
1083 /****************************************************************************
1084 debugging function, dump at level 6 the struct in the logs
1085 ****************************************************************************/
1086 static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1087 {
1088         uint32 success;
1089         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1090         int i;
1091         
1092         DEBUG(106,("Dumping printer driver at level [%d]\n", level));
1093         
1094         switch (level)
1095         {
1096                 case 3: 
1097                 {
1098                         if (driver.info_3 == NULL)
1099                                 success=5;
1100                         else {
1101                                 info3=driver.info_3;
1102                         
1103                                 DEBUGADD(106,("version:[%d]\n",         info3->cversion));
1104                                 DEBUGADD(106,("name:[%s]\n",            info3->name));
1105                                 DEBUGADD(106,("environment:[%s]\n",     info3->environment));
1106                                 DEBUGADD(106,("driverpath:[%s]\n",      info3->driverpath));
1107                                 DEBUGADD(106,("datafile:[%s]\n",        info3->datafile));
1108                                 DEBUGADD(106,("configfile:[%s]\n",      info3->configfile));
1109                                 DEBUGADD(106,("helpfile:[%s]\n",        info3->helpfile));
1110                                 DEBUGADD(106,("monitorname:[%s]\n",     info3->monitorname));
1111                                 DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
1112                                 
1113                                 for (i=0; info3->dependentfiles &&
1114                                           *info3->dependentfiles[i]; i++) {
1115                                         DEBUGADD(106,("dependentfile:[%s]\n", 
1116                                                       info3->dependentfiles[i]));
1117                                 }
1118                                 success=0;
1119                         }
1120                         break;
1121                 }
1122                 default:
1123                         DEBUGADD(1,("Level not implemented\n"));
1124                         success=1;
1125                         break;
1126         }
1127         
1128         return (success);
1129 }
1130
1131 /****************************************************************************
1132 ****************************************************************************/
1133 static int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
1134 {
1135         int len = 0;
1136
1137         len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
1138
1139         if (!nt_devmode) return len;
1140
1141         len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
1142                         nt_devmode->devicename,
1143                         nt_devmode->formname,
1144
1145                         nt_devmode->specversion,
1146                         nt_devmode->driverversion,
1147                         nt_devmode->size,
1148                         nt_devmode->driverextra,
1149                         nt_devmode->orientation,
1150                         nt_devmode->papersize,
1151                         nt_devmode->paperlength,
1152                         nt_devmode->paperwidth,
1153                         nt_devmode->scale,
1154                         nt_devmode->copies,
1155                         nt_devmode->defaultsource,
1156                         nt_devmode->printquality,
1157                         nt_devmode->color,
1158                         nt_devmode->duplex,
1159                         nt_devmode->yresolution,
1160                         nt_devmode->ttoption,
1161                         nt_devmode->collate,
1162                         nt_devmode->logpixels,
1163                         
1164                         nt_devmode->fields,
1165                         nt_devmode->bitsperpel,
1166                         nt_devmode->pelswidth,
1167                         nt_devmode->pelsheight,
1168                         nt_devmode->displayflags,
1169                         nt_devmode->displayfrequency,
1170                         nt_devmode->icmmethod,
1171                         nt_devmode->icmintent,
1172                         nt_devmode->mediatype,
1173                         nt_devmode->dithertype,
1174                         nt_devmode->reserved1,
1175                         nt_devmode->reserved2,
1176                         nt_devmode->panningwidth,
1177                         nt_devmode->panningheight,
1178                         nt_devmode->private);
1179
1180         
1181         if (nt_devmode->private) {
1182                 len += tdb_pack(buf+len, buflen-len, "B",
1183                                 nt_devmode->driverextra,
1184                                 nt_devmode->private);
1185         }
1186
1187         DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname));
1188
1189         return len;
1190 }
1191
1192 /****************************************************************************
1193 ****************************************************************************/
1194 static int pack_specifics(NT_PRINTER_PARAM *param, char *buf, int buflen)
1195 {
1196         int len = 0;
1197
1198         while (param != NULL) {
1199                 len += tdb_pack(buf+len, buflen-len, "pfdB",
1200                                 param,
1201                                 param->value, 
1202                                 param->type, 
1203                                 param->data_len,
1204                                 param->data);
1205                 param=param->next;      
1206         }
1207
1208         len += tdb_pack(buf+len, buflen-len, "p", param);
1209
1210         return len;
1211 }
1212
1213
1214 /****************************************************************************
1215 delete a printer - this just deletes the printer info file, any open
1216 handles are not affected
1217 ****************************************************************************/
1218 uint32 del_a_printer(char *sharename)
1219 {
1220         pstring key;
1221         TDB_DATA kbuf;
1222
1223         slprintf(key, sizeof(key), "%s%s",
1224                  PRINTERS_PREFIX, sharename);
1225
1226         kbuf.dptr=key;
1227         kbuf.dsize=strlen(key)+1;
1228
1229         tdb_delete(tdb, kbuf);
1230         return 0;
1231 }
1232
1233 /****************************************************************************
1234 ****************************************************************************/
1235 static uint32 update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
1236 {
1237         pstring key;
1238         char *buf;
1239         int buflen, len, ret;
1240         TDB_DATA kbuf, dbuf;
1241         
1242         /* 
1243          * in addprinter: no servername and the printer is the name
1244          * in setprinter: servername is \\server
1245          *                and printer is \\server\\printer
1246          *
1247          * Samba manages only local printers.
1248          * we currently don't support things like path=\\other_server\printer
1249          */
1250
1251         if (info->servername[0]!='\0') {
1252                 trim_string(info->printername, info->servername, NULL);
1253                 trim_string(info->printername, "\\", NULL);
1254                 info->servername[0]='\0';
1255         }
1256
1257         /*
1258          * JFM: one day I'll forget.
1259          * below that's info->portname because that's the SAMBA sharename
1260          * and I made NT 'thinks' it's the portname
1261          * the info->sharename is the thing you can name when you add a printer
1262          * that's the short-name when you create shared printer for 95/98
1263          * So I've made a limitation in SAMBA: you can only have 1 printer model
1264          * behind a SAMBA share.
1265          */
1266
1267         buf = NULL;
1268         buflen = 0;
1269
1270  again: 
1271         len = 0;
1272         len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffPfffff",
1273                         info->attributes,
1274                         info->priority,
1275                         info->default_priority,
1276                         info->starttime,
1277                         info->untiltime,
1278                         info->status,
1279                         info->cjobs,
1280                         info->averageppm,
1281                         info->changeid,
1282                         info->c_setprinter,
1283                         info->setuptime,
1284                         info->servername,
1285                         info->printername,
1286                         info->sharename,
1287                         info->portname,
1288                         info->drivername,
1289                         info->comment,
1290                         info->location,
1291                         info->sepfile,
1292                         info->printprocessor,
1293                         info->datatype,
1294                         info->parameters);
1295
1296         len += pack_devicemode(info->devmode, buf+len, buflen-len);
1297         len += pack_specifics(info->specific, buf+len, buflen-len);
1298
1299         if (buflen != len) {
1300                 buf = (char *)Realloc(buf, len);
1301                 buflen = len;
1302                 goto again;
1303         }
1304         
1305
1306         slprintf(key, sizeof(key), "%s%s",
1307                  PRINTERS_PREFIX, info->sharename);
1308
1309         kbuf.dptr = key;
1310         kbuf.dsize = strlen(key)+1;
1311         dbuf.dptr = buf;
1312         dbuf.dsize = len;
1313
1314         ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
1315
1316         if (ret == -1)
1317                 DEBUG(8, ("error updating printer to tdb on disk\n"));
1318
1319         safe_free(buf);
1320
1321         DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n", 
1322                  info->sharename, info->drivername, info->portname, len));
1323
1324         return ret;
1325 }
1326
1327
1328 /****************************************************************************
1329 ****************************************************************************/
1330 BOOL add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
1331 {
1332         NT_PRINTER_PARAM *current;
1333         
1334         DEBUG(108,("add_a_specific_param\n"));  
1335
1336         param->next=NULL;
1337         
1338         if (info_2->specific == NULL)
1339         {
1340                 info_2->specific=param;
1341         }
1342         else
1343         {
1344                 current=info_2->specific;               
1345                 while (current->next != NULL) {
1346                         current=current->next;
1347                 }               
1348                 current->next=param;
1349         }
1350         return (True);
1351 }
1352
1353 /****************************************************************************
1354 ****************************************************************************/
1355 BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
1356 {
1357         NT_PRINTER_PARAM *current;
1358         NT_PRINTER_PARAM *previous;
1359         
1360         current=info_2->specific;
1361         previous=current;
1362         
1363         if (current==NULL) return (False);
1364         
1365         if ( !strcmp(current->value, param->value) && 
1366             (strlen(current->value)==strlen(param->value)) ) {
1367                 DEBUG(109,("deleting first value\n"));
1368                 info_2->specific=current->next;
1369                 safe_free(current->data);
1370                 safe_free(current);
1371                 DEBUG(109,("deleted first value\n"));
1372                 return (True);
1373         }
1374
1375         current=previous->next;
1376                 
1377         while ( current!=NULL ) {
1378                 if (!strcmp(current->value, param->value) &&
1379                     strlen(current->value)==strlen(param->value) ) {
1380                         DEBUG(109,("deleting current value\n"));
1381                         previous->next=current->next;
1382                         safe_free(current->data);
1383                         safe_free(current);
1384                         DEBUG(109,("deleted current value\n"));
1385                         return(True);
1386                 }
1387                 
1388                 previous=previous->next;
1389                 current=current->next;
1390         }
1391         return (False);
1392 }
1393
1394 /****************************************************************************
1395  Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
1396 ****************************************************************************/
1397 static void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr)
1398 {
1399         NT_PRINTER_PARAM *param = *param_ptr;
1400
1401         if(param == NULL)
1402                 return;
1403
1404         DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param->value));
1405
1406         if(param->data)
1407                 safe_free(param->data);
1408
1409         safe_free(param);
1410         *param_ptr = NULL;
1411 }
1412
1413 /****************************************************************************
1414  Malloc and return an NT devicemode.
1415 ****************************************************************************/
1416
1417 NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
1418 {
1419 /*
1420  * should I init this ones ???
1421         nt_devmode->devicename
1422 */
1423
1424         char adevice[32];
1425         NT_DEVICEMODE *nt_devmode = (NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE));
1426
1427         if (nt_devmode == NULL) {
1428                 DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
1429                 return NULL;
1430         }
1431
1432         ZERO_STRUCTP(nt_devmode);
1433
1434         snprintf(adevice, sizeof(adevice), "\\\\%s\\%s", global_myname, default_devicename);
1435         fstrcpy(nt_devmode->devicename, adevice);
1436         
1437         
1438         fstrcpy(nt_devmode->formname, "Letter");
1439
1440         nt_devmode->specversion      = 0x0401;
1441         nt_devmode->driverversion    = 0x0400;
1442         nt_devmode->size             = 0x00DC;
1443         nt_devmode->driverextra      = 0x0000;
1444         nt_devmode->fields           = FORMNAME | TTOPTION | PRINTQUALITY | 
1445                                        DEFAULTSOURCE | COPIES | SCALE | 
1446                                        PAPERSIZE | ORIENTATION;
1447         nt_devmode->orientation      = 1;
1448         nt_devmode->papersize        = PAPER_LETTER;
1449         nt_devmode->paperlength      = 0;
1450         nt_devmode->paperwidth       = 0;
1451         nt_devmode->scale            = 0x64;
1452         nt_devmode->copies           = 01;
1453         nt_devmode->defaultsource    = BIN_FORMSOURCE;
1454         nt_devmode->printquality     = RES_HIGH;           /* 0x0258 */
1455         nt_devmode->color            = COLOR_MONOCHROME;
1456         nt_devmode->duplex           = DUP_SIMPLEX;
1457         nt_devmode->yresolution      = 0;
1458         nt_devmode->ttoption         = TT_SUBDEV;
1459         nt_devmode->collate          = COLLATE_FALSE;
1460         nt_devmode->icmmethod        = 0;
1461         nt_devmode->icmintent        = 0;
1462         nt_devmode->mediatype        = 0;
1463         nt_devmode->dithertype       = 0;
1464
1465         /* non utilisés par un driver d'imprimante */
1466         nt_devmode->logpixels        = 0;
1467         nt_devmode->bitsperpel       = 0;
1468         nt_devmode->pelswidth        = 0;
1469         nt_devmode->pelsheight       = 0;
1470         nt_devmode->displayflags     = 0;
1471         nt_devmode->displayfrequency = 0;
1472         nt_devmode->reserved1        = 0;
1473         nt_devmode->reserved2        = 0;
1474         nt_devmode->panningwidth     = 0;
1475         nt_devmode->panningheight    = 0;
1476         
1477         nt_devmode->private=NULL;
1478
1479         return nt_devmode;
1480 }
1481
1482 /****************************************************************************
1483  Deepcopy an NT devicemode.
1484 ****************************************************************************/
1485
1486 NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
1487 {
1488         NT_DEVICEMODE *new_nt_devicemode = NULL;
1489
1490         if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
1491                 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
1492                 return NULL;
1493         }
1494
1495         new_nt_devicemode->private = NULL;
1496         if (nt_devicemode->private != NULL) {
1497                 if ((new_nt_devicemode->private = memdup(nt_devicemode->private, nt_devicemode->driverextra)) == NULL) {
1498                         safe_free(new_nt_devicemode);
1499                         DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
1500                         return NULL;
1501         }
1502         }
1503
1504         return new_nt_devicemode;
1505 }
1506
1507 /****************************************************************************
1508  Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
1509 ****************************************************************************/
1510
1511 void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
1512 {
1513         NT_DEVICEMODE *nt_devmode = *devmode_ptr;
1514
1515         if(nt_devmode == NULL)
1516                 return;
1517
1518         DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
1519
1520         if(nt_devmode->private)
1521                 safe_free(nt_devmode->private);
1522
1523         safe_free(nt_devmode);
1524         *devmode_ptr = NULL;
1525 }
1526
1527 /****************************************************************************
1528  Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
1529 ****************************************************************************/
1530 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
1531 {
1532         NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
1533         NT_PRINTER_PARAM *param_ptr;
1534
1535         if(info == NULL)
1536                 return;
1537
1538         DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
1539
1540         free_nt_devicemode(&info->devmode);
1541         free_sec_desc_buf(&info->secdesc_buf);
1542
1543         for(param_ptr = info->specific; param_ptr; ) {
1544                 NT_PRINTER_PARAM *tofree = param_ptr;
1545
1546                 param_ptr = param_ptr->next;
1547                 free_nt_printer_param(&tofree);
1548         }
1549
1550         safe_free(*info_ptr);
1551         *info_ptr = NULL;
1552 }
1553
1554
1555 /****************************************************************************
1556 ****************************************************************************/
1557 static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
1558 {
1559         int len = 0;
1560         int extra_len = 0;
1561         NT_DEVICEMODE devmode;
1562
1563         ZERO_STRUCT(devmode);
1564
1565         len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
1566
1567         if (!*nt_devmode) return len;
1568
1569         len += tdb_unpack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
1570                           devmode.devicename,
1571                           devmode.formname,
1572
1573                           &devmode.specversion,
1574                           &devmode.driverversion,
1575                           &devmode.size,
1576                           &devmode.driverextra,
1577                           &devmode.orientation,
1578                           &devmode.papersize,
1579                           &devmode.paperlength,
1580                           &devmode.paperwidth,
1581                           &devmode.scale,
1582                           &devmode.copies,
1583                           &devmode.defaultsource,
1584                           &devmode.printquality,
1585                           &devmode.color,
1586                           &devmode.duplex,
1587                           &devmode.yresolution,
1588                           &devmode.ttoption,
1589                           &devmode.collate,
1590                           &devmode.logpixels,
1591                           
1592                           &devmode.fields,
1593                           &devmode.bitsperpel,
1594                           &devmode.pelswidth,
1595                           &devmode.pelsheight,
1596                           &devmode.displayflags,
1597                           &devmode.displayfrequency,
1598                           &devmode.icmmethod,
1599                           &devmode.icmintent,
1600                           &devmode.mediatype,
1601                           &devmode.dithertype,
1602                           &devmode.reserved1,
1603                           &devmode.reserved2,
1604                           &devmode.panningwidth,
1605                           &devmode.panningheight,
1606                           &devmode.private);
1607         
1608         if (devmode.private) {
1609                 /* the len in tdb_unpack is an int value and
1610                  * devmoce.driverextra is only a short
1611                  */
1612                 len += tdb_unpack(buf+len, buflen-len, "B", &extra_len, &devmode.private);
1613                 devmode.driverextra=(uint16)extra_len;
1614         }
1615
1616         *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
1617
1618         DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode.devicename, devmode.formname));
1619         if (devmode.private)
1620                 DEBUG(8,("with a private section of %d bytes\n", devmode.driverextra));
1621
1622         return len;
1623 }
1624
1625 /****************************************************************************
1626 ****************************************************************************/
1627 static int unpack_specifics(NT_PRINTER_PARAM **list, char *buf, int buflen)
1628 {
1629         int len = 0;
1630         NT_PRINTER_PARAM param, *p;
1631
1632         *list = NULL;
1633
1634         while (1) {
1635                 len += tdb_unpack(buf+len, buflen-len, "p", &p);
1636                 if (!p) break;
1637
1638                 len += tdb_unpack(buf+len, buflen-len, "fdB",
1639                                   param.value, 
1640                                   &param.type, 
1641                                   &param.data_len,
1642                                   &param.data);
1643                 param.next = *list;
1644                 *list = memdup(&param, sizeof(param));
1645
1646                 DEBUG(8,("specific: [%s], len: %d\n", param.value, param.data_len));
1647         }
1648
1649         return len;
1650 }
1651
1652
1653 /****************************************************************************
1654 get a default printer info 2 struct
1655 ****************************************************************************/
1656 static uint32 get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
1657 {
1658         extern pstring global_myname;
1659         int snum;
1660         NT_PRINTER_INFO_LEVEL_2 info;
1661
1662         ZERO_STRUCT(info);
1663
1664         snum = lp_servicenumber(sharename);
1665
1666         fstrcpy(info.servername, global_myname);
1667         fstrcpy(info.printername, sharename);
1668         fstrcpy(info.portname, SAMBA_PRINTER_PORT_NAME);
1669         fstrcpy(info.drivername, lp_printerdriver(snum));
1670         pstrcpy(info.comment, "");
1671         fstrcpy(info.printprocessor, "winprint");
1672         fstrcpy(info.datatype, "RAW");
1673
1674         info.attributes = PRINTER_ATTRIBUTE_SHARED   \
1675                          | PRINTER_ATTRIBUTE_LOCAL  \
1676                          | PRINTER_ATTRIBUTE_RAW_ONLY \
1677                          | PRINTER_ATTRIBUTE_QUEUED ;            /* attributes */
1678
1679         info.starttime = 0; /* Minutes since 12:00am GMT */
1680         info.untiltime = 0; /* Minutes since 12:00am GMT */
1681         info.priority = 1;
1682         info.default_priority = 1;
1683         info.setuptime = (uint32)time(NULL);
1684
1685         if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
1686                 goto fail;
1687
1688         if (!nt_printing_getsec(sharename, &info.secdesc_buf))
1689                 goto fail;
1690
1691         *info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
1692         if (! *info_ptr) {
1693                 DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
1694                 goto fail;
1695         }
1696
1697         return (0);     
1698
1699   fail:
1700
1701         if (info.devmode)
1702                 free_nt_devicemode(&info.devmode);
1703         if (info.secdesc_buf)
1704                 free_sec_desc_buf(&info.secdesc_buf);
1705         return 2;
1706 }
1707
1708 /****************************************************************************
1709 ****************************************************************************/
1710 static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
1711 {
1712         pstring key;
1713         NT_PRINTER_INFO_LEVEL_2 info;
1714         int len = 0;
1715         TDB_DATA kbuf, dbuf;
1716                 
1717         ZERO_STRUCT(info);
1718
1719         slprintf(key, sizeof(key), "%s%s", PRINTERS_PREFIX, sharename);
1720
1721         kbuf.dptr = key;
1722         kbuf.dsize = strlen(key)+1;
1723
1724         dbuf = tdb_fetch(tdb, kbuf);
1725         if (!dbuf.dptr)
1726                 return get_a_printer_2_default(info_ptr, sharename);
1727
1728         len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff",
1729                         &info.attributes,
1730                         &info.priority,
1731                         &info.default_priority,
1732                         &info.starttime,
1733                         &info.untiltime,
1734                         &info.status,
1735                         &info.cjobs,
1736                         &info.averageppm,
1737                         &info.changeid,
1738                         &info.c_setprinter,
1739                         &info.setuptime,
1740                         info.servername,
1741                         info.printername,
1742                         info.sharename,
1743                         info.portname,
1744                         info.drivername,
1745                         info.comment,
1746                         info.location,
1747                         info.sepfile,
1748                         info.printprocessor,
1749                         info.datatype,
1750                         info.parameters);
1751
1752         /* Samba has to have shared raw drivers. */
1753         info.attributes |= (PRINTER_ATTRIBUTE_SHARED|PRINTER_ATTRIBUTE_RAW_ONLY);
1754
1755         len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
1756         len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
1757
1758         nt_printing_getsec(sharename, &info.secdesc_buf);
1759
1760         safe_free(dbuf.dptr);
1761         *info_ptr=memdup(&info, sizeof(info));
1762
1763         DEBUG(9,("Unpacked printer [%s] running driver [%s]\n",
1764                  sharename, info.drivername));
1765
1766         
1767         return 0;       
1768 }
1769
1770 /****************************************************************************
1771 debugging function, dump at level 6 the struct in the logs
1772 ****************************************************************************/
1773 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1774 {
1775         uint32 success;
1776         NT_PRINTER_INFO_LEVEL_2 *info2;
1777         
1778         DEBUG(106,("Dumping printer at level [%d]\n", level));
1779         
1780         switch (level)
1781         {
1782                 case 2: 
1783                 {
1784                         if (printer.info_2 == NULL)
1785                                 success=5;
1786                         else
1787                         {
1788                                 info2=printer.info_2;
1789                         
1790                                 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
1791                                 DEBUGADD(106,("priority:[%d]\n", info2->priority));
1792                                 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
1793                                 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
1794                                 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
1795                                 DEBUGADD(106,("status:[%d]\n", info2->status));
1796                                 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
1797                                 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
1798                                 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
1799                                 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
1800                                 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
1801
1802                                 DEBUGADD(106,("servername:[%s]\n", info2->servername));
1803                                 DEBUGADD(106,("printername:[%s]\n", info2->printername));
1804                                 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
1805                                 DEBUGADD(106,("portname:[%s]\n", info2->portname));
1806                                 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
1807                                 DEBUGADD(106,("comment:[%s]\n", info2->comment));
1808                                 DEBUGADD(106,("location:[%s]\n", info2->location));
1809                                 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
1810                                 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
1811                                 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
1812                                 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
1813                                 success=0;
1814                         }
1815                         break;
1816                 }
1817                 default:
1818                         DEBUGADD(1,("Level not implemented\n"));
1819                         success=1;
1820                         break;
1821         }
1822         
1823         return (success);
1824 }
1825
1826 /****************************************************************************
1827  Get the parameters we can substitute in an NT print job.
1828 ****************************************************************************/
1829
1830 void get_printer_subst_params(int snum, fstring *printername, fstring *sharename, fstring *portname)
1831 {
1832         NT_PRINTER_INFO_LEVEL *printer = NULL;
1833
1834         **printername = **sharename = **portname = '\0';
1835
1836         if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
1837                 return;
1838
1839         fstrcpy(*printername, printer->info_2->printername);
1840         fstrcpy(*sharename, printer->info_2->sharename);
1841         fstrcpy(*portname, printer->info_2->portname);
1842
1843         free_a_printer(&printer, 2);
1844 }
1845
1846 /*
1847  * The function below are the high level ones.
1848  * only those ones must be called from the spoolss code.
1849  * JFM.
1850  */
1851
1852 /****************************************************************************
1853  Modify a printer. This is called from SETPRINTERDATA/DELETEPRINTERDATA.
1854 ****************************************************************************/
1855
1856 uint32 mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1857 {
1858         uint32 success;
1859         
1860         dump_a_printer(printer, level); 
1861         
1862         switch (level)
1863         {
1864                 case 2:
1865                 {
1866                         printer.info_2->c_setprinter++;
1867                         success=update_a_printer_2(printer.info_2);
1868                         break;
1869                 }
1870                 default:
1871                         success=1;
1872                         break;
1873         }
1874         
1875         return (success);
1876 }
1877
1878 /****************************************************************************
1879  Add a printer. This is called from ADDPRINTER(EX) and also SETPRINTER.
1880  We split this out from mod_a_printer as it updates the id's and timestamps.
1881 ****************************************************************************/
1882
1883 uint32 add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1884 {
1885         uint32 success;
1886         
1887         dump_a_printer(printer, level); 
1888         
1889         switch (level)
1890         {
1891                 case 2: 
1892                 {
1893                         /*
1894                          * Update the changestamp.
1895                          * Note we must *not* do this in mod_a_printer().
1896                          */
1897                         NTTIME time_nt;
1898                         time_t time_unix = time(NULL);
1899                         unix_to_nt_time(&time_nt, time_unix);
1900                         printer.info_2->changeid=time_nt.low;
1901
1902                         printer.info_2->c_setprinter++;
1903                         success=update_a_printer_2(printer.info_2);
1904                         break;
1905                 }
1906                 default:
1907                         success=1;
1908                         break;
1909         }
1910         
1911         return (success);
1912 }
1913
1914 /****************************************************************************
1915  Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
1916 ****************************************************************************/
1917
1918 uint32 get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename)
1919 {
1920         uint32 success;
1921         NT_PRINTER_INFO_LEVEL *printer = NULL;
1922         
1923         *pp_printer = NULL;
1924
1925         DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
1926
1927         switch (level)
1928         {
1929                 case 2: 
1930                 {
1931                         if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
1932                                 DEBUG(0,("get_a_printer: malloc fail.\n"));
1933                                 return 1;
1934                         }
1935                         ZERO_STRUCTP(printer);
1936                         success=get_a_printer_2(&printer->info_2, sharename);
1937                         if (success == 0) {
1938                                 dump_a_printer(*printer, level);
1939                                 *pp_printer = printer;
1940                         } else {
1941                                 safe_free(printer);
1942                         }
1943                         break;
1944                 }
1945                 default:
1946                         success=1;
1947                         break;
1948         }
1949         
1950         DEBUG(10,("get_a_printer: [%s] level %u returning %u\n", sharename, (unsigned int)level, (unsigned int)success));
1951
1952         return (success);
1953 }
1954
1955 /****************************************************************************
1956  Deletes a NT_PRINTER_INFO_LEVEL struct.
1957 ****************************************************************************/
1958
1959 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
1960 {
1961         uint32 success;
1962         NT_PRINTER_INFO_LEVEL *printer = *pp_printer;
1963
1964         DEBUG(104,("freeing a printer at level [%d]\n", level));
1965
1966         if (printer == NULL)
1967                 return 0;
1968         
1969         switch (level)
1970         {
1971                 case 2: 
1972                 {
1973                         if (printer->info_2 != NULL)
1974                         {
1975                                 free_nt_printer_info_level_2(&printer->info_2);
1976                                 success=0;
1977                         }
1978                         else
1979                         {
1980                                 success=4;
1981                         }
1982                         break;
1983                 }
1984                 default:
1985                         success=1;
1986                         break;
1987         }
1988
1989         safe_free(printer);
1990         *pp_printer = NULL;
1991         return (success);
1992 }
1993
1994 /****************************************************************************
1995 ****************************************************************************/
1996 uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1997 {
1998         uint32 success;
1999         DEBUG(104,("adding a printer at level [%d]\n", level));
2000         dump_a_printer_driver(driver, level);
2001         
2002         switch (level)
2003         {
2004                 case 3: 
2005                 {
2006                         success=add_a_printer_driver_3(driver.info_3);
2007                         break;
2008                 }
2009
2010                 case 6: 
2011                 {
2012                         success=add_a_printer_driver_6(driver.info_6);
2013                         break;
2014                 }
2015                 default:
2016                         success=1;
2017                         break;
2018         }
2019         
2020         return (success);
2021 }
2022 /****************************************************************************
2023 ****************************************************************************/
2024 uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level, 
2025                             fstring printername, fstring architecture, uint32 version)
2026 {
2027         uint32 success;
2028         
2029         switch (level)
2030         {
2031                 case 3: 
2032                 {
2033                         success=get_a_printer_driver_3(&driver->info_3, printername, architecture, version);
2034                         break;
2035                 }
2036                 default:
2037                         success=1;
2038                         break;
2039         }
2040         
2041         if (success == 0)
2042                 dump_a_printer_driver(*driver, level);
2043         return (success);
2044 }
2045
2046 /****************************************************************************
2047 ****************************************************************************/
2048 uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
2049 {
2050         uint32 success;
2051         
2052         switch (level)
2053         {
2054                 case 3: 
2055                 {
2056                         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
2057                         if (driver.info_3 != NULL)
2058                         {
2059                                 info3=driver.info_3;
2060                                 safe_free(info3->dependentfiles);
2061                                 ZERO_STRUCTP(info3);
2062                                 safe_free(info3);
2063                                 success=0;
2064                         }
2065                         else
2066                         {
2067                                 success=4;
2068                         }
2069                         break;
2070                 }
2071                 case 6: 
2072                 {
2073                         NT_PRINTER_DRIVER_INFO_LEVEL_6 *info6;
2074                         if (driver.info_6 != NULL)
2075                         {
2076                                 info6=driver.info_6;
2077                                 safe_free(info6->dependentfiles);
2078                                 safe_free(info6->previousnames);
2079                                 ZERO_STRUCTP(info6);
2080                                 safe_free(info6);
2081                                 success=0;
2082                         }
2083                         else
2084                         {
2085                                 success=4;
2086                         }
2087                         break;
2088                 }
2089                 default:
2090                         success=1;
2091                         break;
2092         }
2093         return (success);
2094 }
2095
2096 /****************************************************************************
2097 ****************************************************************************/
2098 BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
2099                                  fstring value, uint8 **data, uint32 *type, uint32 *len)
2100 {
2101         /* right now that's enough ! */ 
2102         NT_PRINTER_PARAM *param;
2103         int i=0;
2104         
2105         param=printer.info_2->specific;
2106         
2107         while (param != NULL && i < param_index) {
2108                 param=param->next;
2109                 i++;
2110         }
2111         
2112         if (param == NULL)
2113                 return False;
2114
2115         /* exited because it exist */
2116         *type=param->type;              
2117         StrnCpy(value, param->value, sizeof(fstring)-1);
2118         *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
2119         if(*data == NULL)
2120                 return False;
2121         ZERO_STRUCTP(*data);
2122         memcpy(*data, param->data, param->data_len);
2123         *len=param->data_len;
2124         return True;
2125 }
2126
2127 /****************************************************************************
2128 ****************************************************************************/
2129 BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level, 
2130                         fstring value, uint8 **data, uint32 *type, uint32 *len)
2131 {
2132         /* right now that's enough ! */ 
2133         NT_PRINTER_PARAM *param;
2134         
2135         DEBUG(105, ("get_specific_param\n"));
2136         
2137         param=printer.info_2->specific;
2138                 
2139         while (param != NULL)
2140         {
2141 #if 1 /* JRA - I think this should be case insensitive.... */
2142                 if ( strequal(value, param->value) 
2143 #else
2144                 if ( !strcmp(value, param->value) 
2145 #endif
2146                     && strlen(value)==strlen(param->value))
2147                         break;
2148                         
2149                 param=param->next;
2150         }
2151         
2152         DEBUG(106, ("found one param\n"));
2153         if (param != NULL)
2154         {
2155                 /* exited because it exist */
2156                 *type=param->type;      
2157                 
2158                 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
2159                 if(*data == NULL)
2160                         return False;
2161                 memcpy(*data, param->data, param->data_len);
2162                 *len=param->data_len;
2163
2164                 DEBUG(106, ("exit of get_specific_param:true\n"));
2165                 return (True);
2166         }
2167         DEBUG(106, ("exit of get_specific_param:false\n"));
2168         return (False);
2169 }
2170
2171 /****************************************************************************
2172  Store a security desc for a printer.
2173 ****************************************************************************/
2174
2175 uint32 nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
2176 {
2177         prs_struct ps;
2178         TALLOC_CTX *mem_ctx = NULL;
2179         fstring key;
2180         uint32 status;
2181
2182         mem_ctx = talloc_init();
2183         if (mem_ctx == NULL) return False;
2184
2185         /* Store the security descriptor in a tdb */
2186
2187         prs_init(&ps, (uint32)sec_desc_size(secdesc_ctr->sec) + 
2188                  sizeof(SEC_DESC_BUF), 4, mem_ctx, MARSHALL);
2189
2190         if (!sec_io_desc_buf("nt_printing_setsec", &secdesc_ctr, &ps, 1)) {
2191                 status = ERROR_INVALID_FUNCTION;
2192                 goto done;
2193         }
2194
2195         slprintf(key, sizeof(key), "SECDESC/%s", printername);
2196
2197         if (tdb_prs_store(tdb, key, &ps)==0) {
2198                 status = 0;
2199         } else {
2200                 DEBUG(1,("Failed to store secdesc for %s\n", printername));
2201                 status = ERROR_INVALID_FUNCTION;
2202         }
2203
2204         /* Free mallocated memory */
2205
2206  done:
2207         prs_mem_free(&ps);
2208
2209         if (mem_ctx) talloc_destroy(mem_ctx);
2210
2211         return status;
2212 }
2213
2214 /****************************************************************************
2215  Construct a default security descriptor buffer for a printer.
2216 ****************************************************************************/
2217
2218 static SEC_DESC_BUF *construct_default_printer_sdb(void)
2219 {
2220         SEC_ACE ace[2];
2221         SEC_ACCESS sa;
2222         SEC_ACL *psa = NULL;
2223         SEC_DESC_BUF *sdb = NULL;
2224         SEC_DESC *psd = NULL;
2225         DOM_SID owner_sid;
2226         size_t sd_size;
2227         enum SID_NAME_USE name_type;
2228
2229         /* Create an ACE where Everyone is allowed to print */
2230
2231         init_sec_access(&sa, PRINTER_ACE_PRINT);
2232         init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
2233                      sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
2234
2235
2236         /* Make the security descriptor owned by the Administrators group
2237            on the PDC of the domain. */
2238
2239         if (winbind_lookup_name(lp_workgroup(), &owner_sid, &name_type)) {
2240                 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
2241         } else {
2242
2243                 /* Backup plan - make printer owned by admins or root.  This should
2244                    emulate a lanman printer as security settings can't be
2245                    changed. */
2246
2247                 if (!lookup_name( "Printer Administrators", &owner_sid, &name_type) &&
2248                         !lookup_name( "Administrators", &owner_sid, &name_type) &&
2249                         !lookup_name( "Administrator", &owner_sid, &name_type) &&
2250                         !lookup_name("root", &owner_sid, &name_type)) {
2251                                                 sid_copy(&owner_sid, &global_sid_World);
2252                 }
2253         }
2254
2255         init_sec_access(&sa, PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT);
2256         init_sec_ace(&ace[1], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
2257                      sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
2258
2259         /* The ACL revision number in rpc_secdesc.h differs from the one
2260            created by NT when setting ACE entries in printer
2261            descriptors.  NT4 complains about the property being edited by a
2262            NT5 machine. */
2263
2264 #define NT4_ACL_REVISION 0x2
2265
2266         if ((psa = make_sec_acl(NT4_ACL_REVISION, 2, ace)) != NULL) {
2267                 psd = make_sec_desc(SEC_DESC_REVISION, 
2268                                     SEC_DESC_SELF_RELATIVE | 
2269                                     SEC_DESC_DACL_PRESENT,
2270                                     &owner_sid, NULL,
2271                                     NULL, psa, &sd_size);
2272                 free_sec_acl(&psa);
2273         }
2274
2275         if (!psd) {
2276                 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
2277                 return NULL;
2278         }
2279
2280         sdb = make_sec_desc_buf(sd_size, psd);
2281
2282         DEBUG(4,("construct_default_printer_sdb: size = %u.\n", 
2283                  (unsigned int)sd_size));
2284
2285         free_sec_desc(&psd);
2286         return sdb;
2287 }
2288
2289 /****************************************************************************
2290  Get a security desc for a printer.
2291 ****************************************************************************/
2292
2293 BOOL nt_printing_getsec(char *printername, SEC_DESC_BUF **secdesc_ctr)
2294 {
2295         prs_struct ps;
2296         TALLOC_CTX *mem_ctx = NULL;
2297         fstring key;
2298
2299         mem_ctx = talloc_init();
2300         if (mem_ctx == NULL)
2301                 return False;
2302
2303         /* Fetch security descriptor from tdb */
2304
2305         slprintf(key, sizeof(key), "SECDESC/%s", printername);
2306
2307         if (tdb_prs_fetch(tdb, key, &ps, mem_ctx)!=0 ||
2308             !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
2309
2310                 DEBUG(4,("using default secdesc for %s\n", printername));
2311
2312                 if (!(*secdesc_ctr = construct_default_printer_sdb())) {
2313                         talloc_destroy(mem_ctx);
2314                         return False;
2315                 }
2316
2317                 talloc_destroy(mem_ctx);
2318                 return True;
2319         }
2320
2321         /* If security descriptor is owned by S-1-1-0 and winbindd is up,
2322            this security descriptor has been created when winbindd was
2323            down.  Take ownership of security descriptor. */
2324
2325         if (sid_equal((*secdesc_ctr)->sec->owner_sid, &global_sid_World)) {
2326                 DOM_SID owner_sid;
2327                 enum SID_NAME_USE name_type;
2328
2329                 /* Change sd owner to workgroup administrator */
2330
2331                 if (winbind_lookup_name(lp_workgroup(), &owner_sid,
2332                                         &name_type)) {
2333                         SEC_DESC_BUF *new_secdesc_ctr = NULL;
2334                         SEC_DESC *psd = NULL;
2335                         size_t size;
2336
2337                         /* Create new sd */
2338
2339                         sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
2340
2341                         psd = make_sec_desc((*secdesc_ctr)->sec->revision,
2342                                             (*secdesc_ctr)->sec->type,
2343                                             &owner_sid,
2344                                             (*secdesc_ctr)->sec->grp_sid,
2345                                             (*secdesc_ctr)->sec->sacl,
2346                                             (*secdesc_ctr)->sec->dacl,
2347                                             &size);
2348
2349                         new_secdesc_ctr = make_sec_desc_buf(size, psd);
2350
2351                         free_sec_desc(&psd);
2352
2353                         /* Swap with other one */
2354
2355                         free_sec_desc_buf(secdesc_ctr);
2356                         *secdesc_ctr = new_secdesc_ctr;
2357
2358                         /* Set it */
2359
2360                         nt_printing_setsec(printername, *secdesc_ctr);
2361                 }
2362         }
2363
2364         prs_mem_free(&ps);
2365         talloc_destroy(mem_ctx);
2366         return True;
2367 }
2368
2369 /* error code:
2370         0: everything OK
2371         1: level not implemented
2372         2: file doesn't exist
2373         3: can't allocate memory
2374         4: can't free memory
2375         5: non existant struct
2376 */
2377
2378 /*
2379         A printer and a printer driver are 2 different things.
2380         NT manages them separatelly, Samba does the same.
2381         Why ? Simply because it's easier and it makes sense !
2382         
2383         Now explanation: You have 3 printers behind your samba server,
2384         2 of them are the same make and model (laser A and B). But laser B 
2385         has an 3000 sheet feeder and laser A doesn't such an option.
2386         Your third printer is an old dot-matrix model for the accounting :-).
2387         
2388         If the /usr/local/samba/lib directory (default dir), you will have
2389         5 files to describe all of this.
2390         
2391         3 files for the printers (1 by printer):
2392                 NTprinter_laser A
2393                 NTprinter_laser B
2394                 NTprinter_accounting
2395         2 files for the drivers (1 for the laser and 1 for the dot matrix)
2396                 NTdriver_printer model X
2397                 NTdriver_printer model Y
2398
2399 jfm: I should use this comment for the text file to explain 
2400         same thing for the forms BTW.
2401         Je devrais mettre mes commentaires en francais, ca serait mieux :-)
2402
2403 */
2404
2405 /****************************************************************************
2406  Check a user has permissions to perform the given operation.  We use some
2407  constants defined in include/rpc_spoolss.h that look relevant to check
2408  the various actions we perform when checking printer access.
2409
2410    PRINTER_ACCESS_ADMINISTER:
2411        print_queue_pause, print_queue_resume, update_printer_sec,
2412        update_printer, spoolss_addprinterex_level_2,
2413        _spoolss_setprinterdata
2414         
2415    PRINTER_ACCESS_USE:
2416        print_job_start
2417
2418    JOB_ACCESS_ADMINISTER:
2419        print_job_delete, print_job_pause, print_job_resume,
2420        print_queue_purge
2421
2422  ****************************************************************************/
2423 BOOL print_access_check(struct current_user *user, int snum, int access_type)
2424 {
2425         SEC_DESC_BUF *secdesc = NULL;
2426         uint32 access_granted, status, required_access = 0;
2427         BOOL result;
2428         char *pname;
2429         int i;
2430         extern struct current_user current_user;
2431         
2432         /* If user is NULL then use the current_user structure */
2433
2434         if (!user) user = &current_user;
2435
2436         /* Always allow root or printer admins to do anything */
2437
2438         if (user->uid == 0 ||
2439             user_in_list(uidtoname(user->uid), lp_printer_admin(snum))) {
2440                 return True;
2441         }
2442
2443         /* Get printer name */
2444
2445         pname = PRINTERNAME(snum);
2446
2447         if (!pname || !*pname)
2448                 pname = SERVICE(snum);
2449
2450         if (!pname || !*pname) {
2451                 errno = EACCES;
2452                 return False;
2453         }
2454
2455         /* Get printer security descriptor */
2456
2457         nt_printing_getsec(pname, &secdesc);
2458
2459         /* Check against NT4 ACE mask values.  From observation these
2460            values are:
2461
2462                Access Type       ACE Mask    Constant
2463                -------------------------------------
2464                Full Control      0x10000000  PRINTER_ACE_FULL_CONTROL
2465                Print             0xe0000000  PRINTER_ACE_PRINT
2466                Manage Documents  0x00020000  PRINTER_ACE_MANAGE_DOCUMENTS
2467         */
2468
2469         switch (access_type) {
2470         case PRINTER_ACCESS_USE:
2471                 required_access = PRINTER_ACE_PRINT;
2472                 break;
2473         case PRINTER_ACCESS_ADMINISTER:
2474                 required_access = PRINTER_ACE_MANAGE_DOCUMENTS | 
2475                         PRINTER_ACE_PRINT;
2476                 break;
2477         case JOB_ACCESS_ADMINISTER:
2478                 required_access = PRINTER_ACE_MANAGE_DOCUMENTS;
2479                 break;
2480         default:
2481                 DEBUG(0, ("invalid value passed to print_access_check()\n"));
2482                 result = False;
2483                 goto done;
2484         }       
2485
2486         /* The ACE for Full Control in a printer security descriptor
2487            doesn't seem to map properly to the access checking model.  For
2488            it to work properly it should be the logical OR of all the other
2489            values, i.e PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT.
2490            This would cause the access check to simply fall out when we
2491            check against any subset of these bits.  To get things to work,
2492            change every ACE mask of PRINTER_ACE_FULL_CONTROL to 
2493            PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT before
2494            performing the access check.  I'm sure there is a better way to
2495            do this! */
2496
2497         if (secdesc && secdesc->sec && secdesc->sec->dacl &&
2498             secdesc->sec->dacl->ace) {
2499                 for(i = 0; i < secdesc->sec->dacl->num_aces; i++) {
2500                         if (secdesc->sec->dacl->ace[i].info.mask ==
2501                             PRINTER_ACE_FULL_CONTROL) {
2502                                 secdesc->sec->dacl->ace[i].info.mask =
2503                                         PRINTER_ACE_MANAGE_DOCUMENTS | 
2504                                         PRINTER_ACE_PRINT;
2505                         }
2506                 }
2507         }
2508
2509         if ((result = se_access_check(secdesc->sec, user, required_access, 
2510                                       &access_granted, &status))) {
2511                 goto done;
2512         }
2513
2514         /* Check against NT5 ACE mask values.  From observation these
2515            values are:
2516
2517                Access Type       ACE Mask    Constant
2518                -------------------------------------
2519                Full Control      0x000f000c  PRINTER_ACE_NT5_FULL_CONTROL
2520                Print             0x00020008  PRINTER_ACE_NT5_PRINT
2521                Manage Documents  0x00020000  PRINTER_ACE_NT5_MANAGE_DOCUMENTS
2522
2523            NT5 likes to rewrite the security descriptor and change the ACE
2524            masks from NT4 format to NT5 format making them unreadable by
2525            NT4 clients. */
2526
2527         switch (access_type) {
2528         case PRINTER_ACCESS_USE:
2529                 required_access = PRINTER_ACE_NT5_PRINT;
2530                 break;
2531         case PRINTER_ACCESS_ADMINISTER:
2532                 required_access = PRINTER_ACE_NT5_FULL_CONTROL;
2533                 break;
2534         case JOB_ACCESS_ADMINISTER:
2535                 required_access = PRINTER_ACE_NT5_MANAGE_DOCUMENTS;
2536                 break;
2537         }       
2538
2539         result = se_access_check(secdesc->sec, user, required_access, 
2540                                  &access_granted, &status);
2541
2542         /* Check access */
2543         
2544  done:
2545         DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE"));
2546         
2547         /* Free mallocated memory */
2548
2549         free_sec_desc_buf(&secdesc);
2550
2551         if (!result)
2552                 errno = EACCES;
2553
2554         return result;
2555 }
2556
2557 /****************************************************************************
2558  Check the time parameters allow a print operation.
2559 *****************************************************************************/
2560
2561 BOOL print_time_access_check(int snum)
2562 {
2563         NT_PRINTER_INFO_LEVEL *printer = NULL;
2564         BOOL ok = False;
2565         time_t now = time(NULL);
2566         struct tm *t;
2567         uint32 mins;
2568
2569         if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
2570                 return False;
2571
2572         if (printer->info_2->starttime == 0 && printer->info_2->untiltime == 0)
2573                 ok = True;
2574
2575         t = gmtime(&now);
2576         mins = (uint32)t->tm_hour*60 + (uint32)t->tm_min;
2577
2578         if (mins >= printer->info_2->starttime && mins <= printer->info_2->untiltime)
2579                 ok = True;
2580
2581         free_a_printer(&printer, 2);
2582
2583         if (!ok)
2584                 errno = EACCES;
2585
2586         return ok;
2587 }
2588
2589
2590 #undef OLD_NTDOMAIN