printing/nt_printing.c: After long soul searching and making both Andrew and my
[samba.git] / source3 / printing / nt_printing.c
1 #define OLD_NTDOMAIN 1
2 /* 
3  *  Unix SMB/Netbios implementation.
4  *  Version 1.9.
5  *  RPC Pipe client / server routines
6  *  Copyright (C) Andrew Tridgell              1992-2000,
7  *  Copyright (C) Jean François Micouleau      1998-2000.
8  *  
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *  
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *  
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  */
23
24 #include "includes.h"
25
26 extern int DEBUGLEVEL;
27 extern pstring global_myname;
28 extern DOM_SID global_sid_World; 
29
30 static TDB_CONTEXT *tdb; /* used for driver files */
31
32 #define FORMS_PREFIX "FORMS/"
33 #define DRIVERS_PREFIX "DRIVERS/"
34 #define PRINTERS_PREFIX "PRINTERS/"
35
36 #define DATABASE_VERSION 1
37
38 /* 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, 
631                                   uint32 level, struct current_user *user, uint32 *perr)
632 {
633         NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
634         NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver;
635         fstring architecture;
636         pstring new_dir;
637         pstring old_name;
638         pstring new_name;
639         fstring user_name;
640         fstring null_pw;
641         connection_struct *conn;
642         pstring inbuf;
643         pstring outbuf;
644         struct passwd *pass;
645         int ecode;
646         int outsize = 0;
647         int i;
648
649         *perr = 0;
650         memset(inbuf, '\0', sizeof(inbuf));
651         memset(outbuf, '\0', sizeof(outbuf));
652
653         if (level==3)
654                 driver=driver_abstract.info_3;
655         else if (level==6) {
656                 convert_level_6_to_level3(&converted_driver, driver_abstract.info_6);
657                 driver = &converted_driver;
658         } else {
659                 DEBUG(0,("move_driver_to_download_area: Unknown info level (%u)\n", (unsigned int)level ));
660                 return False;
661         }
662
663         get_short_archi(architecture, driver->environment);
664
665         become_root();
666         pass = getpwuid(user->uid);
667         if(pass == NULL) {
668                 DEBUG(0,("move_driver_to_download_area: Unable to get passwd entry for uid %u\n",
669                                 (unsigned int)user->uid ));
670                 unbecome_root();
671                 return False;
672         }
673         unbecome_root();
674
675         /* connect to the print$ share under the same account as the user connected to the rpc pipe */  
676         fstrcpy(user_name, pass->pw_name );
677         DEBUG(10,("move_driver_to_download_area: uid %d -> user %s\n", (int)user->uid, user_name));
678
679         /* Null password is ok - we are already an authenticated user... */
680         *null_pw = '\0';
681         conn = make_connection("print$", user_name, null_pw, 0, "A:", user->vuid, &ecode);
682
683         if (conn == NULL) {
684                 DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
685                 *perr = (uint32)ecode;
686                 return False;
687         }
688
689         /*
690          * Save who we are - we are temporarily becoming the connection user.
691          */
692
693         push_sec_ctx();
694
695         if (!become_user(conn, conn->vuid)) {
696                 DEBUG(0,("move_driver_to_download_area: Can't become user %s\n", user_name ));
697                 pop_sec_ctx();
698                 return False;
699         }
700
701         /* 
702          * make the directories version and version\driver_name 
703          * under the architecture directory.
704          */
705         DEBUG(5,("Creating first directory\n"));
706         slprintf(new_dir, sizeof(new_dir), "%s\\%d", architecture, driver->cversion);
707         mkdir_internal(conn, inbuf, outbuf, new_dir);
708
709         /* move all the files, one by one, 
710          * from archi\filexxx.yyy to
711          * archi\version\filexxx.yyy
712          *
713          * Note: drivers may list the same file name in several places. This
714          * causes problems on a second attempt to move the file. JRR
715          *
716          * Note: use the replace flag on rename_internals() call, otherwise it
717          * is very difficult to change previously installed drivers... the Windows
718          * GUI offers the user the choice to replace or keep exisitng driver. JRR
719          */
720
721         DEBUG(5,("Moving file now !\n"));
722
723         if (driver->driverpath && strlen(driver->driverpath)) {
724         slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->driverpath);       
725         slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->driverpath);    
726         if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
727                 DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
728                                 old_name, new_name ));
729                 close_cnum(conn, user->vuid);
730                 pop_sec_ctx();
731                 *perr = (uint32)SVAL(outbuf,smb_err);
732                 return False;
733         }
734         }
735
736         if (driver->datafile && strlen(driver->datafile)) {
737         if (!strequal(driver->datafile, driver->driverpath)) {
738                 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->datafile); 
739                 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->datafile);      
740                 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
741                         DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
742                                         old_name, new_name ));
743                         close_cnum(conn, user->vuid);
744                         pop_sec_ctx();
745                         *perr = (uint32)SVAL(outbuf,smb_err);
746                         return False;
747                 }
748         }
749         }
750
751         if (driver->configfile && strlen(driver->configfile)) {
752         if (!strequal(driver->configfile, driver->driverpath) &&
753                 !strequal(driver->configfile, driver->datafile)) {
754                 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->configfile);       
755                 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->configfile);    
756                 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
757                         DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
758                                 old_name, new_name ));
759                         close_cnum(conn, user->vuid);
760                         pop_sec_ctx();
761                         *perr = (uint32)SVAL(outbuf,smb_err);
762                         return False;
763                 }
764         }
765         }
766
767         if (driver->helpfile && strlen(driver->helpfile)) {
768         if (!strequal(driver->helpfile, driver->driverpath) &&
769                         !strequal(driver->helpfile, driver->datafile) &&
770                         !strequal(driver->helpfile, driver->configfile)) {
771                 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->helpfile); 
772                 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->helpfile);      
773                 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
774                         DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
775                                 old_name, new_name ));
776                         close_cnum(conn, user->vuid);
777                         pop_sec_ctx();
778                         *perr = (uint32)SVAL(outbuf,smb_err);
779                         return False;
780                 }
781         }
782         }
783
784         if (driver->dependentfiles) {
785                 for (i=0; *driver->dependentfiles[i]; i++) {
786                         if (!strequal(driver->dependentfiles[i], driver->driverpath) &&
787                                         !strequal(driver->dependentfiles[i], driver->datafile) &&
788                                         !strequal(driver->dependentfiles[i], driver->configfile) &&
789                                         !strequal(driver->dependentfiles[i], driver->helpfile)) {
790                                 int j;
791                                 for (j=0; j < i; j++) {
792                                         if (strequal(driver->dependentfiles[i], driver->dependentfiles[j])) {
793                                                 goto NextDriver;
794                                         }
795                                 }
796
797                                 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->dependentfiles[i]);        
798                                 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->dependentfiles[i]);     
799                                 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
800                                         DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
801                                                 old_name, new_name ));
802                                         close_cnum(conn, user->vuid);
803                                         pop_sec_ctx();
804                                         *perr = (uint32)SVAL(outbuf,smb_err);
805                                         return False;
806                                 }
807                         }
808                 NextDriver: ;
809                 }
810         }
811
812         close_cnum(conn, user->vuid);
813         pop_sec_ctx();
814
815         return True;
816 }
817
818 /****************************************************************************
819 ****************************************************************************/
820 static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
821 {
822         int len, buflen;
823         fstring architecture;
824         pstring directory;
825         pstring temp_name;
826         pstring key;
827         char *buf;
828         int i, ret;
829         TDB_DATA kbuf, dbuf;
830
831         get_short_archi(architecture, driver->environment);
832
833         /* The names are relative. We store them in the form: \print$\arch\version\driver.xxx
834          * \\server is added in the rpc server layer.
835          * It does make sense to NOT store the server's name in the printer TDB.
836          */
837
838         slprintf(directory, sizeof(directory), "\\print$\\%s\\%d\\", architecture, driver->cversion);
839
840         
841         fstrcpy(temp_name, driver->driverpath);
842         slprintf(driver->driverpath, sizeof(driver->driverpath), "%s%s", directory, temp_name);
843
844         fstrcpy(temp_name, driver->datafile);
845         slprintf(driver->datafile, sizeof(driver->datafile), "%s%s", directory, temp_name);
846
847         fstrcpy(temp_name, driver->configfile);
848         slprintf(driver->configfile, sizeof(driver->configfile), "%s%s", directory, temp_name);
849
850         fstrcpy(temp_name, driver->helpfile);
851         slprintf(driver->helpfile, sizeof(driver->helpfile), "%s%s", directory, temp_name);
852
853         if (driver->dependentfiles) {
854                 for (i=0; *driver->dependentfiles[i]; i++) {
855                         fstrcpy(temp_name, driver->dependentfiles[i]);
856                         slprintf(driver->dependentfiles[i], sizeof(driver->dependentfiles[i]), "%s%s", directory, temp_name);
857                 }
858         }
859
860         slprintf(key, sizeof(key), "%s%s/%d/%s", DRIVERS_PREFIX, architecture, driver->cversion, driver->name);
861
862         DEBUG(5,("add_a_printer_driver_3: Adding driver with key %s\n", key ));
863
864         buf = NULL;
865         len = buflen = 0;
866
867  again:
868         len = 0;
869         len += tdb_pack(buf+len, buflen-len, "dffffffff", 
870                         driver->cversion,
871                         driver->name,
872                         driver->environment,
873                         driver->driverpath,
874                         driver->datafile,
875                         driver->configfile,
876                         driver->helpfile,
877                         driver->monitorname,
878                         driver->defaultdatatype);
879
880         if (driver->dependentfiles) {
881                 for (i=0; *driver->dependentfiles[i]; i++) {
882                         len += tdb_pack(buf+len, buflen-len, "f", 
883                                         driver->dependentfiles[i]);
884                 }
885         }
886
887         if (len != buflen) {
888                 buf = (char *)Realloc(buf, len);
889                 buflen = len;
890                 goto again;
891         }
892
893
894         kbuf.dptr = key;
895         kbuf.dsize = strlen(key)+1;
896         dbuf.dptr = buf;
897         dbuf.dsize = len;
898         
899         ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
900
901         if (ret)
902                 DEBUG(0,("add_a_printer_driver_3: Adding driver with key %s failed.\n", key ));
903
904         safe_free(buf);
905         return ret;
906 }
907
908 /****************************************************************************
909 ****************************************************************************/
910 static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
911 {
912         NT_PRINTER_DRIVER_INFO_LEVEL_3 info3;
913
914         ZERO_STRUCT(info3);
915         info3.cversion = driver->version;
916         fstrcpy(info3.name,driver->name);
917         fstrcpy(info3.environment,driver->environment);
918         fstrcpy(info3.driverpath,driver->driverpath);
919         fstrcpy(info3.datafile,driver->datafile);
920         fstrcpy(info3.configfile,driver->configfile);
921         fstrcpy(info3.helpfile,driver->helpfile);
922         fstrcpy(info3.monitorname,driver->monitorname);
923         fstrcpy(info3.defaultdatatype,driver->defaultdatatype);
924         info3.dependentfiles = driver->dependentfiles;
925
926         return add_a_printer_driver_3(&info3);
927 }
928
929
930 /****************************************************************************
931 ****************************************************************************/
932 static uint32 get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
933 {
934         NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
935
936         ZERO_STRUCT(info);
937
938         fstrcpy(info.name, in_prt);
939         fstrcpy(info.defaultdatatype, "RAW");
940         
941         fstrcpy(info.driverpath, "");
942         fstrcpy(info.datafile, "");
943         fstrcpy(info.configfile, "");
944         fstrcpy(info.helpfile, "");
945
946         if ((info.dependentfiles=(fstring *)malloc(2*sizeof(fstring))) == NULL)
947                 return ERROR_NOT_ENOUGH_MEMORY;
948
949         memset(info.dependentfiles, '\0', 2*sizeof(fstring));
950         fstrcpy(info.dependentfiles[0], "");
951
952         *info_ptr = memdup(&info, sizeof(info));
953         
954         return 0;       
955 }
956
957 /****************************************************************************
958 ****************************************************************************/
959 static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch, uint32 version)
960 {
961         NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
962         TDB_DATA kbuf, dbuf;
963         fstring architecture;
964         int len = 0;
965         int i;
966         pstring key;
967
968         ZERO_STRUCT(driver);
969
970         get_short_archi(architecture, in_arch);
971
972         DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, in_prt));
973
974         slprintf(key, sizeof(key), "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, in_prt);
975
976         kbuf.dptr = key;
977         kbuf.dsize = strlen(key)+1;
978         
979         dbuf = tdb_fetch(tdb, kbuf);
980 #if 0
981         if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
982 #else
983         if (!dbuf.dptr) return 5;
984 #endif
985         len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff", 
986                           &driver.cversion,
987                           driver.name,
988                           driver.environment,
989                           driver.driverpath,
990                           driver.datafile,
991                           driver.configfile,
992                           driver.helpfile,
993                           driver.monitorname,
994                           driver.defaultdatatype);
995
996         i=0;
997         while (len < dbuf.dsize) {
998                 driver.dependentfiles = (fstring *)Realloc(driver.dependentfiles,
999                                                          sizeof(fstring)*(i+2));
1000                 if (driver.dependentfiles == NULL)
1001                         break;
1002
1003                 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f", 
1004                                   &driver.dependentfiles[i]);
1005                 i++;
1006         }
1007         if (driver.dependentfiles != NULL)
1008                 fstrcpy(driver.dependentfiles[i], "");
1009
1010         safe_free(dbuf.dptr);
1011
1012         if (len != dbuf.dsize) {
1013                 if (driver.dependentfiles != NULL)
1014                         safe_free(driver.dependentfiles);
1015
1016                 return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
1017         }
1018
1019         *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
1020
1021         return 0;
1022 }
1023
1024 /****************************************************************************
1025 ****************************************************************************/
1026 uint32 get_a_printer_driver_9x_compatible(pstring line, fstring model)
1027 {
1028         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1029         TDB_DATA kbuf;
1030         pstring key;
1031         int i;
1032         line[0] = '\0';
1033
1034         slprintf(key, sizeof(key), "%s%s/%d/%s", DRIVERS_PREFIX, "WIN40", 0, model);
1035         DEBUG(10,("driver key: [%s]\n", key));
1036         
1037         kbuf.dptr = key;
1038         kbuf.dsize = strlen(key)+1;
1039         if (!tdb_exists(tdb, kbuf)) return False;
1040
1041         ZERO_STRUCT(info3);
1042         get_a_printer_driver_3(&info3, model, "Windows 4.0", 0);
1043         
1044     DEBUGADD(10,("info3->name            [%s]\n", info3->name));
1045     DEBUGADD(10,("info3->datafile        [%s]\n", info3->datafile));
1046     DEBUGADD(10,("info3->helpfile        [%s]\n", info3->helpfile));
1047     DEBUGADD(10,("info3->monitorname     [%s]\n", info3->monitorname));
1048     DEBUGADD(10,("info3->defaultdatatype [%s]\n", info3->defaultdatatype));
1049         for (i=0; info3->dependentfiles && *info3->dependentfiles[i]; i++) {
1050     DEBUGADD(10,("info3->dependentfiles  [%s]\n", info3->dependentfiles[i]));
1051     }
1052     DEBUGADD(10,("info3->environment     [%s]\n", info3->environment));
1053     DEBUGADD(10,("info3->driverpath      [%s]\n", info3->driverpath));
1054     DEBUGADD(10,("info3->configfile      [%s]\n", info3->configfile));
1055
1056         /*pstrcat(line, info3->name);             pstrcat(line, ":");*/
1057         trim_string(info3->configfile, "\\print$\\WIN40\\0\\", 0);
1058         pstrcat(line, info3->configfile);
1059     pstrcat(line, ":");
1060         trim_string(info3->datafile, "\\print$\\WIN40\\0\\", 0);
1061         pstrcat(line, info3->datafile);
1062     pstrcat(line, ":");
1063         trim_string(info3->helpfile, "\\print$\\WIN40\\0\\", 0);
1064         pstrcat(line, info3->helpfile);
1065     pstrcat(line, ":");
1066         trim_string(info3->monitorname, "\\print$\\WIN40\\0\\", 0);
1067         pstrcat(line, info3->monitorname);
1068     pstrcat(line, ":");
1069         pstrcat(line, "RAW");                /*info3->defaultdatatype);*/
1070     pstrcat(line, ":");
1071
1072         for (i=0; info3->dependentfiles &&
1073                  *info3->dependentfiles[i]; i++) {
1074                 if (i) pstrcat(line, ",");               /* don't end in a "," */
1075                 trim_string(info3->dependentfiles[i], "\\print$\\WIN40\\0\\", 0);
1076                 pstrcat(line, info3->dependentfiles[i]);
1077         }
1078         
1079         free(info3);
1080
1081         return True;    
1082 }
1083
1084 /****************************************************************************
1085 debugging function, dump at level 6 the struct in the logs
1086 ****************************************************************************/
1087 static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1088 {
1089         uint32 success;
1090         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1091         int i;
1092         
1093         DEBUG(106,("Dumping printer driver at level [%d]\n", level));
1094         
1095         switch (level)
1096         {
1097                 case 3: 
1098                 {
1099                         if (driver.info_3 == NULL)
1100                                 success=5;
1101                         else {
1102                                 info3=driver.info_3;
1103                         
1104                                 DEBUGADD(106,("version:[%d]\n",         info3->cversion));
1105                                 DEBUGADD(106,("name:[%s]\n",            info3->name));
1106                                 DEBUGADD(106,("environment:[%s]\n",     info3->environment));
1107                                 DEBUGADD(106,("driverpath:[%s]\n",      info3->driverpath));
1108                                 DEBUGADD(106,("datafile:[%s]\n",        info3->datafile));
1109                                 DEBUGADD(106,("configfile:[%s]\n",      info3->configfile));
1110                                 DEBUGADD(106,("helpfile:[%s]\n",        info3->helpfile));
1111                                 DEBUGADD(106,("monitorname:[%s]\n",     info3->monitorname));
1112                                 DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
1113                                 
1114                                 for (i=0; info3->dependentfiles &&
1115                                           *info3->dependentfiles[i]; i++) {
1116                                         DEBUGADD(106,("dependentfile:[%s]\n", 
1117                                                       info3->dependentfiles[i]));
1118                                 }
1119                                 success=0;
1120                         }
1121                         break;
1122                 }
1123                 default:
1124                         DEBUGADD(1,("Level not implemented\n"));
1125                         success=1;
1126                         break;
1127         }
1128         
1129         return (success);
1130 }
1131
1132 /****************************************************************************
1133 ****************************************************************************/
1134 static int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
1135 {
1136         int len = 0;
1137
1138         len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
1139
1140         if (!nt_devmode) return len;
1141
1142         len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
1143                         nt_devmode->devicename,
1144                         nt_devmode->formname,
1145
1146                         nt_devmode->specversion,
1147                         nt_devmode->driverversion,
1148                         nt_devmode->size,
1149                         nt_devmode->driverextra,
1150                         nt_devmode->orientation,
1151                         nt_devmode->papersize,
1152                         nt_devmode->paperlength,
1153                         nt_devmode->paperwidth,
1154                         nt_devmode->scale,
1155                         nt_devmode->copies,
1156                         nt_devmode->defaultsource,
1157                         nt_devmode->printquality,
1158                         nt_devmode->color,
1159                         nt_devmode->duplex,
1160                         nt_devmode->yresolution,
1161                         nt_devmode->ttoption,
1162                         nt_devmode->collate,
1163                         nt_devmode->logpixels,
1164                         
1165                         nt_devmode->fields,
1166                         nt_devmode->bitsperpel,
1167                         nt_devmode->pelswidth,
1168                         nt_devmode->pelsheight,
1169                         nt_devmode->displayflags,
1170                         nt_devmode->displayfrequency,
1171                         nt_devmode->icmmethod,
1172                         nt_devmode->icmintent,
1173                         nt_devmode->mediatype,
1174                         nt_devmode->dithertype,
1175                         nt_devmode->reserved1,
1176                         nt_devmode->reserved2,
1177                         nt_devmode->panningwidth,
1178                         nt_devmode->panningheight,
1179                         nt_devmode->private);
1180
1181         
1182         if (nt_devmode->private) {
1183                 len += tdb_pack(buf+len, buflen-len, "B",
1184                                 nt_devmode->driverextra,
1185                                 nt_devmode->private);
1186         }
1187
1188         DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname));
1189
1190         return len;
1191 }
1192
1193 /****************************************************************************
1194 ****************************************************************************/
1195 static int pack_specifics(NT_PRINTER_PARAM *param, char *buf, int buflen)
1196 {
1197         int len = 0;
1198
1199         while (param != NULL) {
1200                 len += tdb_pack(buf+len, buflen-len, "pfdB",
1201                                 param,
1202                                 param->value, 
1203                                 param->type, 
1204                                 param->data_len,
1205                                 param->data);
1206                 param=param->next;      
1207         }
1208
1209         len += tdb_pack(buf+len, buflen-len, "p", param);
1210
1211         return len;
1212 }
1213
1214
1215 /****************************************************************************
1216 delete a printer - this just deletes the printer info file, any open
1217 handles are not affected
1218 ****************************************************************************/
1219 uint32 del_a_printer(char *sharename)
1220 {
1221         pstring key;
1222         TDB_DATA kbuf;
1223
1224         slprintf(key, sizeof(key), "%s%s",
1225                  PRINTERS_PREFIX, sharename);
1226
1227         kbuf.dptr=key;
1228         kbuf.dsize=strlen(key)+1;
1229
1230         tdb_delete(tdb, kbuf);
1231         return 0;
1232 }
1233
1234 /****************************************************************************
1235 ****************************************************************************/
1236 static uint32 update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
1237 {
1238         pstring key;
1239         char *buf;
1240         int buflen, len, ret;
1241         TDB_DATA kbuf, dbuf;
1242         
1243         /* 
1244          * in addprinter: no servername and the printer is the name
1245          * in setprinter: servername is \\server
1246          *                and printer is \\server\\printer
1247          *
1248          * Samba manages only local printers.
1249          * we currently don't support things like path=\\other_server\printer
1250          */
1251
1252         if (info->servername[0]!='\0') {
1253                 trim_string(info->printername, info->servername, NULL);
1254                 trim_string(info->printername, "\\", NULL);
1255                 info->servername[0]='\0';
1256         }
1257
1258         /*
1259          * JFM: one day I'll forget.
1260          * below that's info->portname because that's the SAMBA sharename
1261          * and I made NT 'thinks' it's the portname
1262          * the info->sharename is the thing you can name when you add a printer
1263          * that's the short-name when you create shared printer for 95/98
1264          * So I've made a limitation in SAMBA: you can only have 1 printer model
1265          * behind a SAMBA share.
1266          */
1267
1268         buf = NULL;
1269         buflen = 0;
1270
1271  again: 
1272         len = 0;
1273         len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffPfffff",
1274                         info->attributes,
1275                         info->priority,
1276                         info->default_priority,
1277                         info->starttime,
1278                         info->untiltime,
1279                         info->status,
1280                         info->cjobs,
1281                         info->averageppm,
1282                         info->changeid,
1283                         info->c_setprinter,
1284                         info->setuptime,
1285                         info->servername,
1286                         info->printername,
1287                         info->sharename,
1288                         info->portname,
1289                         info->drivername,
1290                         info->comment,
1291                         info->location,
1292                         info->sepfile,
1293                         info->printprocessor,
1294                         info->datatype,
1295                         info->parameters);
1296
1297         len += pack_devicemode(info->devmode, buf+len, buflen-len);
1298         len += pack_specifics(info->specific, buf+len, buflen-len);
1299
1300         if (buflen != len) {
1301                 buf = (char *)Realloc(buf, len);
1302                 buflen = len;
1303                 goto again;
1304         }
1305         
1306
1307         slprintf(key, sizeof(key), "%s%s",
1308                  PRINTERS_PREFIX, info->sharename);
1309
1310         kbuf.dptr = key;
1311         kbuf.dsize = strlen(key)+1;
1312         dbuf.dptr = buf;
1313         dbuf.dsize = len;
1314
1315         ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
1316
1317         if (ret == -1)
1318                 DEBUG(8, ("error updating printer to tdb on disk\n"));
1319
1320         safe_free(buf);
1321
1322         DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n", 
1323                  info->sharename, info->drivername, info->portname, len));
1324
1325         return ret;
1326 }
1327
1328
1329 /****************************************************************************
1330 ****************************************************************************/
1331 BOOL add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
1332 {
1333         NT_PRINTER_PARAM *current;
1334         
1335         DEBUG(108,("add_a_specific_param\n"));  
1336
1337         param->next=NULL;
1338         
1339         if (info_2->specific == NULL)
1340         {
1341                 info_2->specific=param;
1342         }
1343         else
1344         {
1345                 current=info_2->specific;               
1346                 while (current->next != NULL) {
1347                         current=current->next;
1348                 }               
1349                 current->next=param;
1350         }
1351         return (True);
1352 }
1353
1354 /****************************************************************************
1355 ****************************************************************************/
1356 BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
1357 {
1358         NT_PRINTER_PARAM *current;
1359         NT_PRINTER_PARAM *previous;
1360         
1361         current=info_2->specific;
1362         previous=current;
1363         
1364         if (current==NULL) return (False);
1365         
1366         if ( !strcmp(current->value, param->value) && 
1367             (strlen(current->value)==strlen(param->value)) ) {
1368                 DEBUG(109,("deleting first value\n"));
1369                 info_2->specific=current->next;
1370                 safe_free(current->data);
1371                 safe_free(current);
1372                 DEBUG(109,("deleted first value\n"));
1373                 return (True);
1374         }
1375
1376         current=previous->next;
1377                 
1378         while ( current!=NULL ) {
1379                 if (!strcmp(current->value, param->value) &&
1380                     strlen(current->value)==strlen(param->value) ) {
1381                         DEBUG(109,("deleting current value\n"));
1382                         previous->next=current->next;
1383                         safe_free(current->data);
1384                         safe_free(current);
1385                         DEBUG(109,("deleted current value\n"));
1386                         return(True);
1387                 }
1388                 
1389                 previous=previous->next;
1390                 current=current->next;
1391         }
1392         return (False);
1393 }
1394
1395 /****************************************************************************
1396  Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
1397 ****************************************************************************/
1398 static void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr)
1399 {
1400         NT_PRINTER_PARAM *param = *param_ptr;
1401
1402         if(param == NULL)
1403                 return;
1404
1405         DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param->value));
1406
1407         if(param->data)
1408                 safe_free(param->data);
1409
1410         safe_free(param);
1411         *param_ptr = NULL;
1412 }
1413
1414 /****************************************************************************
1415  Malloc and return an NT devicemode.
1416 ****************************************************************************/
1417
1418 NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
1419 {
1420 /*
1421  * should I init this ones ???
1422         nt_devmode->devicename
1423 */
1424
1425         char adevice[32];
1426         NT_DEVICEMODE *nt_devmode = (NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE));
1427
1428         if (nt_devmode == NULL) {
1429                 DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
1430                 return NULL;
1431         }
1432
1433         ZERO_STRUCTP(nt_devmode);
1434
1435         safe_strcpy(adevice, default_devicename, sizeof(adevice));
1436         fstrcpy(nt_devmode->devicename, adevice);       
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         slprintf(info.servername, sizeof(info.servername), "\\\\%s", global_myname);
1667         fstrcpy(info.sharename, sharename);
1668         fstrcpy(info.portname, SAMBA_PRINTER_PORT_NAME);
1669         fstrcpy(info.drivername, lp_printerdriver(snum));
1670         if (*info.drivername == '\0')
1671                 fstrcpy(info.drivername, "NO DRIVER AVAILABLE");
1672
1673         slprintf(info.printername, sizeof(info.printername), "\\\\%s\\%s", global_myname, sharename);
1674         pstrcpy(info.comment, "");
1675         fstrcpy(info.printprocessor, "winprint");
1676         fstrcpy(info.datatype, "RAW");
1677
1678         info.attributes = PRINTER_ATTRIBUTE_SHARED   \
1679                          | PRINTER_ATTRIBUTE_LOCAL  \
1680                          | PRINTER_ATTRIBUTE_RAW_ONLY \
1681                          | PRINTER_ATTRIBUTE_QUEUED ;            /* attributes */
1682
1683         info.starttime = 0; /* Minutes since 12:00am GMT */
1684         info.untiltime = 0; /* Minutes since 12:00am GMT */
1685         info.priority = 1;
1686         info.default_priority = 1;
1687         info.setuptime = (uint32)time(NULL);
1688
1689         if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
1690                 goto fail;
1691
1692         if (!nt_printing_getsec(sharename, &info.secdesc_buf))
1693                 goto fail;
1694
1695         *info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
1696         if (! *info_ptr) {
1697                 DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
1698                 goto fail;
1699         }
1700
1701         return (0);     
1702
1703   fail:
1704
1705         if (info.devmode)
1706                 free_nt_devicemode(&info.devmode);
1707         if (info.secdesc_buf)
1708                 free_sec_desc_buf(&info.secdesc_buf);
1709         return 2;
1710 }
1711
1712 /****************************************************************************
1713 ****************************************************************************/
1714 static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
1715 {
1716         pstring key;
1717         NT_PRINTER_INFO_LEVEL_2 info;
1718         int len = 0;
1719         TDB_DATA kbuf, dbuf;
1720         fstring printername;
1721                 
1722         ZERO_STRUCT(info);
1723
1724         slprintf(key, sizeof(key), "%s%s", PRINTERS_PREFIX, sharename);
1725
1726         kbuf.dptr = key;
1727         kbuf.dsize = strlen(key)+1;
1728
1729         dbuf = tdb_fetch(tdb, kbuf);
1730         if (!dbuf.dptr)
1731                 return get_a_printer_2_default(info_ptr, sharename);
1732
1733         len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff",
1734                         &info.attributes,
1735                         &info.priority,
1736                         &info.default_priority,
1737                         &info.starttime,
1738                         &info.untiltime,
1739                         &info.status,
1740                         &info.cjobs,
1741                         &info.averageppm,
1742                         &info.changeid,
1743                         &info.c_setprinter,
1744                         &info.setuptime,
1745                         info.servername,
1746                         info.printername,
1747                         info.sharename,
1748                         info.portname,
1749                         info.drivername,
1750                         info.comment,
1751                         info.location,
1752                         info.sepfile,
1753                         info.printprocessor,
1754                         info.datatype,
1755                         info.parameters);
1756
1757         /* Samba has to have shared raw drivers. */
1758         info.attributes |= (PRINTER_ATTRIBUTE_SHARED|PRINTER_ATTRIBUTE_RAW_ONLY);
1759
1760         /* Restore the stripped strings. */
1761         slprintf(info.servername, sizeof(info.servername), "\\\\%s", global_myname);
1762         slprintf(printername, sizeof(printername), "\\\\%s\\%s", global_myname,
1763                         info.printername);
1764         fstrcpy(info.printername, printername);
1765
1766         len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
1767         len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
1768
1769         nt_printing_getsec(sharename, &info.secdesc_buf);
1770
1771         safe_free(dbuf.dptr);
1772         *info_ptr=memdup(&info, sizeof(info));
1773
1774         DEBUG(9,("Unpacked printer [%s] name [%s] running driver [%s]\n",
1775                  sharename, info.printername, info.drivername));
1776
1777         
1778         return 0;       
1779 }
1780
1781 /****************************************************************************
1782 debugging function, dump at level 6 the struct in the logs
1783 ****************************************************************************/
1784 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1785 {
1786         uint32 success;
1787         NT_PRINTER_INFO_LEVEL_2 *info2;
1788         
1789         DEBUG(106,("Dumping printer at level [%d]\n", level));
1790         
1791         switch (level)
1792         {
1793                 case 2: 
1794                 {
1795                         if (printer.info_2 == NULL)
1796                                 success=5;
1797                         else
1798                         {
1799                                 info2=printer.info_2;
1800                         
1801                                 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
1802                                 DEBUGADD(106,("priority:[%d]\n", info2->priority));
1803                                 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
1804                                 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
1805                                 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
1806                                 DEBUGADD(106,("status:[%d]\n", info2->status));
1807                                 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
1808                                 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
1809                                 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
1810                                 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
1811                                 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
1812
1813                                 DEBUGADD(106,("servername:[%s]\n", info2->servername));
1814                                 DEBUGADD(106,("printername:[%s]\n", info2->printername));
1815                                 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
1816                                 DEBUGADD(106,("portname:[%s]\n", info2->portname));
1817                                 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
1818                                 DEBUGADD(106,("comment:[%s]\n", info2->comment));
1819                                 DEBUGADD(106,("location:[%s]\n", info2->location));
1820                                 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
1821                                 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
1822                                 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
1823                                 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
1824                                 success=0;
1825                         }
1826                         break;
1827                 }
1828                 default:
1829                         DEBUGADD(1,("Level not implemented\n"));
1830                         success=1;
1831                         break;
1832         }
1833         
1834         return (success);
1835 }
1836
1837 /****************************************************************************
1838  Get the parameters we can substitute in an NT print job.
1839 ****************************************************************************/
1840
1841 void get_printer_subst_params(int snum, fstring *printername, fstring *sharename, fstring *portname)
1842 {
1843         NT_PRINTER_INFO_LEVEL *printer = NULL;
1844
1845         **printername = **sharename = **portname = '\0';
1846
1847         if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
1848                 return;
1849
1850         fstrcpy(*printername, printer->info_2->printername);
1851         fstrcpy(*sharename, printer->info_2->sharename);
1852         fstrcpy(*portname, printer->info_2->portname);
1853
1854         free_a_printer(&printer, 2);
1855 }
1856
1857 /*
1858  * The function below are the high level ones.
1859  * only those ones must be called from the spoolss code.
1860  * JFM.
1861  */
1862
1863 /****************************************************************************
1864  Modify a printer. This is called from SETPRINTERDATA/DELETEPRINTERDATA.
1865 ****************************************************************************/
1866
1867 uint32 mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1868 {
1869         uint32 success;
1870         
1871         dump_a_printer(printer, level); 
1872         
1873         switch (level)
1874         {
1875                 case 2:
1876                 {
1877                         printer.info_2->c_setprinter++;
1878                         success=update_a_printer_2(printer.info_2);
1879                         break;
1880                 }
1881                 default:
1882                         success=1;
1883                         break;
1884         }
1885         
1886         return (success);
1887 }
1888
1889 /****************************************************************************
1890  Add a printer. This is called from ADDPRINTER(EX) and also SETPRINTER.
1891  We split this out from mod_a_printer as it updates the id's and timestamps.
1892 ****************************************************************************/
1893
1894 uint32 add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1895 {
1896         uint32 success;
1897         
1898         dump_a_printer(printer, level); 
1899         
1900         switch (level)
1901         {
1902                 case 2: 
1903                 {
1904                         /*
1905                          * Update the changestamp.
1906                          * Note we must *not* do this in mod_a_printer().
1907                          */
1908                         NTTIME time_nt;
1909                         time_t time_unix = time(NULL);
1910                         unix_to_nt_time(&time_nt, time_unix);
1911                         printer.info_2->changeid=time_nt.low;
1912
1913                         printer.info_2->c_setprinter++;
1914                         success=update_a_printer_2(printer.info_2);
1915                         break;
1916                 }
1917                 default:
1918                         success=1;
1919                         break;
1920         }
1921         
1922         return (success);
1923 }
1924
1925 /****************************************************************************
1926  Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
1927 ****************************************************************************/
1928
1929 uint32 get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename)
1930 {
1931         uint32 success;
1932         NT_PRINTER_INFO_LEVEL *printer = NULL;
1933         
1934         *pp_printer = NULL;
1935
1936         DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
1937
1938         switch (level)
1939         {
1940                 case 2: 
1941                 {
1942                         if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
1943                                 DEBUG(0,("get_a_printer: malloc fail.\n"));
1944                                 return 1;
1945                         }
1946                         ZERO_STRUCTP(printer);
1947                         success=get_a_printer_2(&printer->info_2, sharename);
1948                         if (success == 0) {
1949                                 dump_a_printer(*printer, level);
1950                                 *pp_printer = printer;
1951                         } else {
1952                                 safe_free(printer);
1953                         }
1954                         break;
1955                 }
1956                 default:
1957                         success=1;
1958                         break;
1959         }
1960         
1961         DEBUG(10,("get_a_printer: [%s] level %u returning %u\n", sharename, (unsigned int)level, (unsigned int)success));
1962
1963         return (success);
1964 }
1965
1966 /****************************************************************************
1967  Deletes a NT_PRINTER_INFO_LEVEL struct.
1968 ****************************************************************************/
1969
1970 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
1971 {
1972         uint32 success;
1973         NT_PRINTER_INFO_LEVEL *printer = *pp_printer;
1974
1975         DEBUG(104,("freeing a printer at level [%d]\n", level));
1976
1977         if (printer == NULL)
1978                 return 0;
1979         
1980         switch (level)
1981         {
1982                 case 2: 
1983                 {
1984                         if (printer->info_2 != NULL)
1985                         {
1986                                 free_nt_printer_info_level_2(&printer->info_2);
1987                                 success=0;
1988                         }
1989                         else
1990                         {
1991                                 success=4;
1992                         }
1993                         break;
1994                 }
1995                 default:
1996                         success=1;
1997                         break;
1998         }
1999
2000         safe_free(printer);
2001         *pp_printer = NULL;
2002         return (success);
2003 }
2004
2005 /****************************************************************************
2006 ****************************************************************************/
2007 uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
2008 {
2009         uint32 success;
2010         DEBUG(104,("adding a printer at level [%d]\n", level));
2011         dump_a_printer_driver(driver, level);
2012         
2013         switch (level)
2014         {
2015                 case 3: 
2016                 {
2017                         success=add_a_printer_driver_3(driver.info_3);
2018                         break;
2019                 }
2020
2021                 case 6: 
2022                 {
2023                         success=add_a_printer_driver_6(driver.info_6);
2024                         break;
2025                 }
2026                 default:
2027                         success=1;
2028                         break;
2029         }
2030         
2031         return (success);
2032 }
2033 /****************************************************************************
2034 ****************************************************************************/
2035 uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level, 
2036                             fstring printername, fstring architecture, uint32 version)
2037 {
2038         uint32 success;
2039         
2040         switch (level)
2041         {
2042                 case 3: 
2043                 {
2044                         success=get_a_printer_driver_3(&driver->info_3, printername, architecture, version);
2045                         break;
2046                 }
2047                 default:
2048                         success=1;
2049                         break;
2050         }
2051         
2052         if (success == 0)
2053                 dump_a_printer_driver(*driver, level);
2054         return (success);
2055 }
2056
2057 /****************************************************************************
2058 ****************************************************************************/
2059 uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
2060 {
2061         uint32 success;
2062         
2063         switch (level)
2064         {
2065                 case 3: 
2066                 {
2067                         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
2068                         if (driver.info_3 != NULL)
2069                         {
2070                                 info3=driver.info_3;
2071                                 safe_free(info3->dependentfiles);
2072                                 ZERO_STRUCTP(info3);
2073                                 safe_free(info3);
2074                                 success=0;
2075                         }
2076                         else
2077                         {
2078                                 success=4;
2079                         }
2080                         break;
2081                 }
2082                 case 6: 
2083                 {
2084                         NT_PRINTER_DRIVER_INFO_LEVEL_6 *info6;
2085                         if (driver.info_6 != NULL)
2086                         {
2087                                 info6=driver.info_6;
2088                                 safe_free(info6->dependentfiles);
2089                                 safe_free(info6->previousnames);
2090                                 ZERO_STRUCTP(info6);
2091                                 safe_free(info6);
2092                                 success=0;
2093                         }
2094                         else
2095                         {
2096                                 success=4;
2097                         }
2098                         break;
2099                 }
2100                 default:
2101                         success=1;
2102                         break;
2103         }
2104         return (success);
2105 }
2106
2107 /****************************************************************************
2108 ****************************************************************************/
2109 BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
2110                                  fstring value, uint8 **data, uint32 *type, uint32 *len)
2111 {
2112         /* right now that's enough ! */ 
2113         NT_PRINTER_PARAM *param;
2114         int i=0;
2115         
2116         param=printer.info_2->specific;
2117         
2118         while (param != NULL && i < param_index) {
2119                 param=param->next;
2120                 i++;
2121         }
2122         
2123         if (param == NULL)
2124                 return False;
2125
2126         /* exited because it exist */
2127         *type=param->type;              
2128         StrnCpy(value, param->value, sizeof(fstring)-1);
2129         *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
2130         if(*data == NULL)
2131                 return False;
2132         ZERO_STRUCTP(*data);
2133         memcpy(*data, param->data, param->data_len);
2134         *len=param->data_len;
2135         return True;
2136 }
2137
2138 /****************************************************************************
2139 ****************************************************************************/
2140 BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level, 
2141                         fstring value, uint8 **data, uint32 *type, uint32 *len)
2142 {
2143         /* right now that's enough ! */ 
2144         NT_PRINTER_PARAM *param;
2145         
2146         DEBUG(105, ("get_specific_param\n"));
2147         
2148         param=printer.info_2->specific;
2149                 
2150         while (param != NULL)
2151         {
2152 #if 1 /* JRA - I think this should be case insensitive.... */
2153                 if ( strequal(value, param->value) 
2154 #else
2155                 if ( !strcmp(value, param->value) 
2156 #endif
2157                     && strlen(value)==strlen(param->value))
2158                         break;
2159                         
2160                 param=param->next;
2161         }
2162         
2163         DEBUG(106, ("found one param\n"));
2164         if (param != NULL)
2165         {
2166                 /* exited because it exist */
2167                 *type=param->type;      
2168                 
2169                 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
2170                 if(*data == NULL)
2171                         return False;
2172                 memcpy(*data, param->data, param->data_len);
2173                 *len=param->data_len;
2174
2175                 DEBUG(106, ("exit of get_specific_param:true\n"));
2176                 return (True);
2177         }
2178         DEBUG(106, ("exit of get_specific_param:false\n"));
2179         return (False);
2180 }
2181
2182 /****************************************************************************
2183  Store a security desc for a printer.
2184 ****************************************************************************/
2185
2186 uint32 nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
2187 {
2188         prs_struct ps;
2189         TALLOC_CTX *mem_ctx = NULL;
2190         fstring key;
2191         uint32 status;
2192
2193         mem_ctx = talloc_init();
2194         if (mem_ctx == NULL) return False;
2195
2196         /* Store the security descriptor in a tdb */
2197
2198         prs_init(&ps, (uint32)sec_desc_size(secdesc_ctr->sec) + 
2199                  sizeof(SEC_DESC_BUF), 4, mem_ctx, MARSHALL);
2200
2201         if (!sec_io_desc_buf("nt_printing_setsec", &secdesc_ctr, &ps, 1)) {
2202                 status = ERROR_INVALID_FUNCTION;
2203                 goto done;
2204         }
2205
2206         slprintf(key, sizeof(key), "SECDESC/%s", printername);
2207
2208         if (tdb_prs_store(tdb, key, &ps)==0) {
2209                 status = 0;
2210         } else {
2211                 DEBUG(1,("Failed to store secdesc for %s\n", printername));
2212                 status = ERROR_INVALID_FUNCTION;
2213         }
2214
2215         /* Free mallocated memory */
2216
2217  done:
2218         prs_mem_free(&ps);
2219
2220         if (mem_ctx) talloc_destroy(mem_ctx);
2221
2222         return status;
2223 }
2224
2225 /****************************************************************************
2226  Construct a default security descriptor buffer for a printer.
2227 ****************************************************************************/
2228
2229 static SEC_DESC_BUF *construct_default_printer_sdb(void)
2230 {
2231         SEC_ACE ace[2];
2232         SEC_ACCESS sa;
2233         SEC_ACL *psa = NULL;
2234         SEC_DESC_BUF *sdb = NULL;
2235         SEC_DESC *psd = NULL;
2236         DOM_SID owner_sid;
2237         size_t sd_size;
2238         enum SID_NAME_USE name_type;
2239
2240         /* Create an ACE where Everyone is allowed to print */
2241
2242         init_sec_access(&sa, PRINTER_ACE_PRINT);
2243         init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
2244                      sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
2245
2246
2247         /* Make the security descriptor owned by the Administrators group
2248            on the PDC of the domain. */
2249
2250         if (winbind_lookup_name(lp_workgroup(), &owner_sid, &name_type)) {
2251                 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
2252         } else {
2253
2254                 /* Backup plan - make printer owned by admins or root.  This should
2255                    emulate a lanman printer as security settings can't be
2256                    changed. */
2257
2258                 if (!lookup_name( "Printer Administrators", &owner_sid, &name_type) &&
2259                         !lookup_name( "Administrators", &owner_sid, &name_type) &&
2260                         !lookup_name( "Administrator", &owner_sid, &name_type) &&
2261                         !lookup_name("root", &owner_sid, &name_type)) {
2262                                                 sid_copy(&owner_sid, &global_sid_World);
2263                 }
2264         }
2265
2266         init_sec_access(&sa, PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT);
2267         init_sec_ace(&ace[1], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
2268                      sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
2269
2270         /* The ACL revision number in rpc_secdesc.h differs from the one
2271            created by NT when setting ACE entries in printer
2272            descriptors.  NT4 complains about the property being edited by a
2273            NT5 machine. */
2274
2275 #define NT4_ACL_REVISION 0x2
2276
2277         if ((psa = make_sec_acl(NT4_ACL_REVISION, 2, ace)) != NULL) {
2278                 psd = make_sec_desc(SEC_DESC_REVISION, 
2279                                     SEC_DESC_SELF_RELATIVE | 
2280                                     SEC_DESC_DACL_PRESENT,
2281                                     &owner_sid, NULL,
2282                                     NULL, psa, &sd_size);
2283                 free_sec_acl(&psa);
2284         }
2285
2286         if (!psd) {
2287                 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
2288                 return NULL;
2289         }
2290
2291         sdb = make_sec_desc_buf(sd_size, psd);
2292
2293         DEBUG(4,("construct_default_printer_sdb: size = %u.\n", 
2294                  (unsigned int)sd_size));
2295
2296         free_sec_desc(&psd);
2297         return sdb;
2298 }
2299
2300 /****************************************************************************
2301  Get a security desc for a printer.
2302 ****************************************************************************/
2303
2304 BOOL nt_printing_getsec(char *printername, SEC_DESC_BUF **secdesc_ctr)
2305 {
2306         prs_struct ps;
2307         TALLOC_CTX *mem_ctx = NULL;
2308         fstring key;
2309
2310         mem_ctx = talloc_init();
2311         if (mem_ctx == NULL)
2312                 return False;
2313
2314         /* Fetch security descriptor from tdb */
2315
2316         slprintf(key, sizeof(key), "SECDESC/%s", printername);
2317
2318         if (tdb_prs_fetch(tdb, key, &ps, mem_ctx)!=0 ||
2319             !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
2320
2321                 DEBUG(4,("using default secdesc for %s\n", printername));
2322
2323                 if (!(*secdesc_ctr = construct_default_printer_sdb())) {
2324                         talloc_destroy(mem_ctx);
2325                         return False;
2326                 }
2327
2328                 talloc_destroy(mem_ctx);
2329                 return True;
2330         }
2331
2332         /* If security descriptor is owned by S-1-1-0 and winbindd is up,
2333            this security descriptor has been created when winbindd was
2334            down.  Take ownership of security descriptor. */
2335
2336         if (sid_equal((*secdesc_ctr)->sec->owner_sid, &global_sid_World)) {
2337                 DOM_SID owner_sid;
2338                 enum SID_NAME_USE name_type;
2339
2340                 /* Change sd owner to workgroup administrator */
2341
2342                 if (winbind_lookup_name(lp_workgroup(), &owner_sid,
2343                                         &name_type)) {
2344                         SEC_DESC_BUF *new_secdesc_ctr = NULL;
2345                         SEC_DESC *psd = NULL;
2346                         size_t size;
2347
2348                         /* Create new sd */
2349
2350                         sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
2351
2352                         psd = make_sec_desc((*secdesc_ctr)->sec->revision,
2353                                             (*secdesc_ctr)->sec->type,
2354                                             &owner_sid,
2355                                             (*secdesc_ctr)->sec->grp_sid,
2356                                             (*secdesc_ctr)->sec->sacl,
2357                                             (*secdesc_ctr)->sec->dacl,
2358                                             &size);
2359
2360                         new_secdesc_ctr = make_sec_desc_buf(size, psd);
2361
2362                         free_sec_desc(&psd);
2363
2364                         /* Swap with other one */
2365
2366                         free_sec_desc_buf(secdesc_ctr);
2367                         *secdesc_ctr = new_secdesc_ctr;
2368
2369                         /* Set it */
2370
2371                         nt_printing_setsec(printername, *secdesc_ctr);
2372                 }
2373         }
2374
2375         prs_mem_free(&ps);
2376         talloc_destroy(mem_ctx);
2377         return True;
2378 }
2379
2380 /* error code:
2381         0: everything OK
2382         1: level not implemented
2383         2: file doesn't exist
2384         3: can't allocate memory
2385         4: can't free memory
2386         5: non existant struct
2387 */
2388
2389 /*
2390         A printer and a printer driver are 2 different things.
2391         NT manages them separatelly, Samba does the same.
2392         Why ? Simply because it's easier and it makes sense !
2393         
2394         Now explanation: You have 3 printers behind your samba server,
2395         2 of them are the same make and model (laser A and B). But laser B 
2396         has an 3000 sheet feeder and laser A doesn't such an option.
2397         Your third printer is an old dot-matrix model for the accounting :-).
2398         
2399         If the /usr/local/samba/lib directory (default dir), you will have
2400         5 files to describe all of this.
2401         
2402         3 files for the printers (1 by printer):
2403                 NTprinter_laser A
2404                 NTprinter_laser B
2405                 NTprinter_accounting
2406         2 files for the drivers (1 for the laser and 1 for the dot matrix)
2407                 NTdriver_printer model X
2408                 NTdriver_printer model Y
2409
2410 jfm: I should use this comment for the text file to explain 
2411         same thing for the forms BTW.
2412         Je devrais mettre mes commentaires en francais, ca serait mieux :-)
2413
2414 */
2415
2416 /****************************************************************************
2417  Check a user has permissions to perform the given operation.  We use some
2418  constants defined in include/rpc_spoolss.h that look relevant to check
2419  the various actions we perform when checking printer access.
2420
2421    PRINTER_ACCESS_ADMINISTER:
2422        print_queue_pause, print_queue_resume, update_printer_sec,
2423        update_printer, spoolss_addprinterex_level_2,
2424        _spoolss_setprinterdata
2425         
2426    PRINTER_ACCESS_USE:
2427        print_job_start
2428
2429    JOB_ACCESS_ADMINISTER:
2430        print_job_delete, print_job_pause, print_job_resume,
2431        print_queue_purge
2432
2433  ****************************************************************************/
2434 BOOL print_access_check(struct current_user *user, int snum, int access_type)
2435 {
2436         SEC_DESC_BUF *secdesc = NULL;
2437         uint32 access_granted, status, required_access = 0;
2438         BOOL result;
2439         char *pname;
2440         int i;
2441         extern struct current_user current_user;
2442         
2443         /* If user is NULL then use the current_user structure */
2444
2445         if (!user) user = &current_user;
2446
2447         /* Always allow root or printer admins to do anything */
2448
2449         if (user->uid == 0 ||
2450             user_in_list(uidtoname(user->uid), lp_printer_admin(snum))) {
2451                 return True;
2452         }
2453
2454         /* Get printer name */
2455
2456         pname = PRINTERNAME(snum);
2457
2458         if (!pname || !*pname)
2459                 pname = SERVICE(snum);
2460
2461         if (!pname || !*pname) {
2462                 errno = EACCES;
2463                 return False;
2464         }
2465
2466         /* Get printer security descriptor */
2467
2468         nt_printing_getsec(pname, &secdesc);
2469
2470         /* Check against NT4 ACE mask values.  From observation these
2471            values are:
2472
2473                Access Type       ACE Mask    Constant
2474                -------------------------------------
2475                Full Control      0x10000000  PRINTER_ACE_FULL_CONTROL
2476                Print             0xe0000000  PRINTER_ACE_PRINT
2477                Manage Documents  0x00020000  PRINTER_ACE_MANAGE_DOCUMENTS
2478         */
2479
2480         switch (access_type) {
2481         case PRINTER_ACCESS_USE:
2482                 required_access = PRINTER_ACE_PRINT;
2483                 break;
2484         case PRINTER_ACCESS_ADMINISTER:
2485                 required_access = PRINTER_ACE_MANAGE_DOCUMENTS | 
2486                         PRINTER_ACE_PRINT;
2487                 break;
2488         case JOB_ACCESS_ADMINISTER:
2489                 required_access = PRINTER_ACE_MANAGE_DOCUMENTS;
2490                 break;
2491         default:
2492                 DEBUG(0, ("invalid value passed to print_access_check()\n"));
2493                 result = False;
2494                 goto done;
2495         }       
2496
2497         /* The ACE for Full Control in a printer security descriptor
2498            doesn't seem to map properly to the access checking model.  For
2499            it to work properly it should be the logical OR of all the other
2500            values, i.e PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT.
2501            This would cause the access check to simply fall out when we
2502            check against any subset of these bits.  To get things to work,
2503            change every ACE mask of PRINTER_ACE_FULL_CONTROL to 
2504            PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT before
2505            performing the access check.  I'm sure there is a better way to
2506            do this! */
2507
2508         if (secdesc && secdesc->sec && secdesc->sec->dacl &&
2509             secdesc->sec->dacl->ace) {
2510                 for(i = 0; i < secdesc->sec->dacl->num_aces; i++) {
2511                         if (secdesc->sec->dacl->ace[i].info.mask ==
2512                             PRINTER_ACE_FULL_CONTROL) {
2513                                 secdesc->sec->dacl->ace[i].info.mask =
2514                                         PRINTER_ACE_MANAGE_DOCUMENTS | 
2515                                         PRINTER_ACE_PRINT;
2516                         }
2517                 }
2518         }
2519
2520         if ((result = se_access_check(secdesc->sec, user, required_access, 
2521                                       &access_granted, &status))) {
2522                 goto done;
2523         }
2524
2525         /* Check against NT5 ACE mask values.  From observation these
2526            values are:
2527
2528                Access Type       ACE Mask    Constant
2529                -------------------------------------
2530                Full Control      0x000f000c  PRINTER_ACE_NT5_FULL_CONTROL
2531                Print             0x00020008  PRINTER_ACE_NT5_PRINT
2532                Manage Documents  0x00020000  PRINTER_ACE_NT5_MANAGE_DOCUMENTS
2533
2534            NT5 likes to rewrite the security descriptor and change the ACE
2535            masks from NT4 format to NT5 format making them unreadable by
2536            NT4 clients. */
2537
2538         switch (access_type) {
2539         case PRINTER_ACCESS_USE:
2540                 required_access = PRINTER_ACE_NT5_PRINT;
2541                 break;
2542         case PRINTER_ACCESS_ADMINISTER:
2543                 required_access = PRINTER_ACE_NT5_FULL_CONTROL;
2544                 break;
2545         case JOB_ACCESS_ADMINISTER:
2546                 required_access = PRINTER_ACE_NT5_MANAGE_DOCUMENTS;
2547                 break;
2548         }       
2549
2550         result = se_access_check(secdesc->sec, user, required_access, 
2551                                  &access_granted, &status);
2552
2553         /* Check access */
2554         
2555  done:
2556         DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE"));
2557         
2558         /* Free mallocated memory */
2559
2560         free_sec_desc_buf(&secdesc);
2561
2562         if (!result)
2563                 errno = EACCES;
2564
2565         return result;
2566 }
2567
2568 /****************************************************************************
2569  Check the time parameters allow a print operation.
2570 *****************************************************************************/
2571
2572 BOOL print_time_access_check(int snum)
2573 {
2574         NT_PRINTER_INFO_LEVEL *printer = NULL;
2575         BOOL ok = False;
2576         time_t now = time(NULL);
2577         struct tm *t;
2578         uint32 mins;
2579
2580         if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
2581                 return False;
2582
2583         if (printer->info_2->starttime == 0 && printer->info_2->untiltime == 0)
2584                 ok = True;
2585
2586         t = gmtime(&now);
2587         mins = (uint32)t->tm_hour*60 + (uint32)t->tm_min;
2588
2589         if (mins >= printer->info_2->starttime && mins <= printer->info_2->untiltime)
2590                 ok = True;
2591
2592         free_a_printer(&printer, 2);
2593
2594         if (!ok)
2595                 errno = EACCES;
2596
2597         return ok;
2598 }
2599
2600
2601 #undef OLD_NTDOMAIN