Re-instated lanman printing security checks (oops).
[samba.git] / source / printing / nt_printing.c
1 /* 
2  *  Unix SMB/Netbios implementation.
3  *  Version 1.9.
4  *  RPC Pipe client / server routines
5  *  Copyright (C) Andrew Tridgell              1992-2000,
6  *  Copyright (C) Jean François Micouleau      1998-2000.
7  *  
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *  
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *  
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22
23 #include "includes.h"
24
25 extern int DEBUGLEVEL;
26 extern pstring global_myname;
27
28 static TDB_CONTEXT *tdb; /* used for driver files */
29
30 #define FORMS_PREFIX "FORMS/"
31 #define DRIVERS_PREFIX "DRIVERS/"
32 #define PRINTERS_PREFIX "PRINTERS/"
33
34 #define DATABASE_VERSION 1
35
36 /* we need to have a small set of default forms to support our
37    default printer */
38 static nt_forms_struct default_forms[] = {
39         {"Letter", 0x20, 0x34b5b, 0x44367, 0x0, 0x0, 0x34b5b, 0x44367},
40         {"A4", 0xb0, 0x3354f, 0x4884e, 0x0, 0x0, 0x3354f, 0x4884e}
41 };
42
43
44 /****************************************************************************
45 open the NT printing tdb
46 ****************************************************************************/
47 BOOL nt_printing_init(void)
48 {
49         static pid_t local_pid;
50
51         if (tdb && local_pid == sys_getpid()) return True;
52         tdb = tdb_open(lock_path("ntdrivers.tdb"), 0, 0, O_RDWR|O_CREAT, 0600);
53         if (!tdb) {
54                 DEBUG(0,("Failed to open nt drivers database\n"));
55                 return False;
56         }
57
58         local_pid = sys_getpid();
59
60         /* handle a Samba upgrade */
61         tdb_writelock(tdb);
62         if (tdb_fetch_int(tdb, "INFO/version") != DATABASE_VERSION) {
63                 tdb_traverse(tdb, (tdb_traverse_func)tdb_delete, NULL);
64                 tdb_store_int(tdb, "INFO/version", DATABASE_VERSION);
65         }
66         tdb_writeunlock(tdb);
67
68         return True;
69 }
70
71   
72 /****************************************************************************
73 get a form struct list
74 ****************************************************************************/
75 int get_ntforms(nt_forms_struct **list)
76 {
77         TDB_DATA kbuf, newkey, dbuf;
78         nt_forms_struct form;
79         int ret;
80         int n = 0;
81
82         for (kbuf = tdb_firstkey(tdb); 
83              kbuf.dptr; 
84              newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
85                 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0) continue;
86                 
87                 dbuf = tdb_fetch(tdb, kbuf);
88                 if (!dbuf.dptr) continue;
89
90                 fstrcpy(form.name, kbuf.dptr+strlen(FORMS_PREFIX));
91                 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddddddd",
92                                  &form.flag, &form.width, &form.length, &form.left,
93                                  &form.top, &form.right, &form.bottom);
94                 safe_free(dbuf.dptr);
95                 if (ret != dbuf.dsize) continue;
96
97                 *list = Realloc(*list, sizeof(nt_forms_struct)*(n+1));
98                 (*list)[n] = form;
99                 n++;
100         }
101
102         /* we should never return a null forms list or NT gets unhappy */
103         if (n == 0) {
104                 *list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));
105                 n = sizeof(default_forms) / sizeof(default_forms[0]);
106         }
107         
108
109         return n;
110 }
111
112 /****************************************************************************
113 write a form struct list
114 ****************************************************************************/
115 int write_ntforms(nt_forms_struct **list, int number)
116 {
117         pstring buf, key;
118         int len;
119         TDB_DATA kbuf,dbuf;
120         int i;
121
122         for (i=0;i<number;i++) {
123                 len = tdb_pack(buf, sizeof(buf), "ddddddd", 
124                                (*list)[i].flag, (*list)[i].width, (*list)[i].length,
125                                (*list)[i].left, (*list)[i].top, (*list)[i].right, 
126                                (*list)[i].bottom);
127                 if (len > sizeof(buf)) break;
128                 slprintf(key, sizeof(key), "%s%s", FORMS_PREFIX, (*list)[i].name);
129                 kbuf.dsize = strlen(key)+1;
130                 kbuf.dptr = key;
131                 dbuf.dsize = len;
132                 dbuf.dptr = buf;
133                 if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) break;
134        }
135
136        return i;
137 }
138
139 /****************************************************************************
140 add a form struct at the end of the list
141 ****************************************************************************/
142 BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
143 {
144         int n=0;
145         BOOL update;
146         fstring form_name;
147
148         /* 
149          * NT tries to add forms even when 
150          * they are already in the base
151          * only update the values if already present
152          */
153
154         update=False;
155         
156         unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
157         for (n=0; n<*count && update==False; n++)
158         {
159                 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
160                 {
161                         DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
162                         update=True;
163                 }
164         }
165
166         if (update==False)
167         {
168                 if((*list=Realloc(*list, (n+1)*sizeof(nt_forms_struct))) == NULL)
169                         return False;
170                 unistr2_to_ascii((*list)[n].name, &(form->name), sizeof((*list)[n].name)-1);
171                 (*count)++;
172         }
173         
174         (*list)[n].flag=form->flags;
175         (*list)[n].width=form->size_x;
176         (*list)[n].length=form->size_y;
177         (*list)[n].left=form->left;
178         (*list)[n].top=form->top;
179         (*list)[n].right=form->right;
180         (*list)[n].bottom=form->bottom;
181
182         return True;
183 }
184
185 /****************************************************************************
186 update a form struct 
187 ****************************************************************************/
188 void update_a_form(nt_forms_struct **list, const FORM *form, int count)
189 {
190         int n=0;
191         fstring form_name;
192         unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
193
194         DEBUG(106, ("[%s]\n", form_name));
195         for (n=0; n<count; n++)
196         {
197                 DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
198                 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
199                         break;
200         }
201
202         if (n==count) return;
203
204         (*list)[n].flag=form->flags;
205         (*list)[n].width=form->size_x;
206         (*list)[n].length=form->size_y;
207         (*list)[n].left=form->left;
208         (*list)[n].top=form->top;
209         (*list)[n].right=form->right;
210         (*list)[n].bottom=form->bottom;
211 }
212  
213 /****************************************************************************
214 get the nt drivers list
215
216 traverse the database and look-up the matching names
217 ****************************************************************************/
218 int get_ntdrivers(fstring **list, char *architecture)
219 {
220         int total=0;
221         fstring short_archi;
222         pstring key;
223         TDB_DATA kbuf, newkey;
224
225         get_short_archi(short_archi, architecture);
226         slprintf(key, sizeof(key), "%s%s/", DRIVERS_PREFIX, short_archi);
227
228         for (kbuf = tdb_firstkey(tdb); 
229              kbuf.dptr; 
230              newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
231                 if (strncmp(kbuf.dptr, key, strlen(key)) != 0) continue;
232                 
233                 if((*list = Realloc(*list, sizeof(fstring)*(total+1))) == NULL)
234                         return -1;
235
236                 fstrcpy((*list)[total], kbuf.dptr+strlen(key));
237                 total++;
238         }
239
240         return(total);
241 }
242
243 /****************************************************************************
244 function to do the mapping between the long architecture name and
245 the short one.
246 ****************************************************************************/
247 void get_short_archi(char *short_archi, char *long_archi)
248 {
249         struct table {
250                 char *long_archi;
251                 char *short_archi;
252         };
253         
254         struct table archi_table[]=
255         {
256                 {"Windows 4.0",          "WIN40"    },
257                 {"Windows NT x86",       "W32X86"   },
258                 {"Windows NT R4000",     "W32mips"  },
259                 {"Windows NT Alpha_AXP", "W32alpha" },
260                 {"Windows NT PowerPC",   "W32ppc"   },
261                 {NULL,                   ""         }
262         };
263         
264         int i=-1;
265
266         DEBUG(107,("Getting architecture dependant directory\n"));
267         do {
268                 i++;
269         } while ( (archi_table[i].long_archi!=NULL ) && strncmp(long_archi, archi_table[i].long_archi, strlen(long_archi)) );
270
271         if (archi_table[i].long_archi==NULL)
272         {
273                 DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
274         }
275         StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
276
277         DEBUGADD(108,("index: [%d]\n", i));
278         DEBUGADD(108,("long architecture: [%s]\n", long_archi));
279         DEBUGADD(108,("short architecture: [%s]\n", short_archi));
280 }
281
282 /****************************************************************************
283 ****************************************************************************/
284 static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
285 {
286         int len, buflen;
287         fstring architecture;
288         pstring key;
289         char *buf;
290         int i, ret;
291         TDB_DATA kbuf, dbuf;
292
293         get_short_archi(architecture, driver->environment);
294         slprintf(key, sizeof(key), "%s%s/%s", DRIVERS_PREFIX, architecture, driver->name);
295
296         /*
297          * cversion must be 2.
298          * when adding a printer ON the SERVER
299          * rpcAddPrinterDriver defines it to zero
300          * which is wrong !!!
301          *
302          * JFM, 4/14/99
303          */
304         driver->cversion=2;
305         
306         buf = NULL;
307         len = buflen = 0;
308
309  again:
310         len = 0;
311         len += tdb_pack(buf+len, buflen-len, "dffffffff", 
312                         driver->cversion,
313                         driver->name,
314                         driver->environment,
315                         driver->driverpath,
316                         driver->datafile,
317                         driver->configfile,
318                         driver->helpfile,
319                         driver->monitorname,
320                         driver->defaultdatatype);
321         
322         if (driver->dependentfiles) {
323                 for (i=0; *driver->dependentfiles[i]; i++) {
324                         len += tdb_pack(buf+len, buflen-len, "f", 
325                                         driver->dependentfiles[i]);
326                 }
327         }
328
329         if (len != buflen) {
330                 buf = (char *)Realloc(buf, len);
331                 buflen = len;
332                 goto again;
333         }
334
335
336         kbuf.dptr = key;
337         kbuf.dsize = strlen(key)+1;
338         dbuf.dptr = buf;
339         dbuf.dsize = len;
340         
341         ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
342
343         safe_free(buf);
344         return ret;
345 }
346
347 /****************************************************************************
348 ****************************************************************************/
349 static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
350 {
351         NT_PRINTER_DRIVER_INFO_LEVEL_3 info3;
352
353         ZERO_STRUCT(info3);
354         info3.cversion = driver->version;
355         fstrcpy(info3.environment,driver->environment);
356         fstrcpy(info3.driverpath,driver->driverpath);
357         fstrcpy(info3.datafile,driver->datafile);
358         fstrcpy(info3.configfile,driver->configfile);
359         fstrcpy(info3.helpfile,driver->helpfile);
360         fstrcpy(info3.monitorname,driver->monitorname);
361         fstrcpy(info3.defaultdatatype,driver->defaultdatatype);
362         info3.dependentfiles = driver->dependentfiles;
363
364         return add_a_printer_driver_3(&info3);
365 }
366
367
368 /****************************************************************************
369 ****************************************************************************/
370 static uint32 get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
371 {
372         NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
373
374         ZERO_STRUCT(info);
375
376         fstrcpy(info.name, in_prt);
377         fstrcpy(info.defaultdatatype, "RAW");
378         
379         fstrcpy(info.driverpath, "");
380         fstrcpy(info.datafile, "");
381         fstrcpy(info.configfile, "");
382         fstrcpy(info.helpfile, "");
383
384         if ((info.dependentfiles=(fstring *)malloc(2*sizeof(fstring))) == NULL)
385                 return ERROR_NOT_ENOUGH_MEMORY;
386
387         memset(info.dependentfiles, '\0', 2*sizeof(fstring));
388         fstrcpy(info.dependentfiles[0], "");
389
390         *info_ptr = memdup(&info, sizeof(info));
391         
392         return 0;       
393 }
394
395 /****************************************************************************
396 ****************************************************************************/
397 static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
398 {
399         NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
400         TDB_DATA kbuf, dbuf;
401         fstring architecture;
402         int len = 0;
403         int i;
404         pstring key;
405
406         ZERO_STRUCT(driver);
407
408         get_short_archi(architecture, in_arch);
409         slprintf(key, sizeof(key), "%s%s/%s", DRIVERS_PREFIX, architecture, in_prt);
410
411         kbuf.dptr = key;
412         kbuf.dsize = strlen(key)+1;
413         
414         dbuf = tdb_fetch(tdb, kbuf);
415         if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
416
417         len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff", 
418                           &driver.cversion,
419                           driver.name,
420                           driver.environment,
421                           driver.driverpath,
422                           driver.datafile,
423                           driver.configfile,
424                           driver.helpfile,
425                           driver.monitorname,
426                           driver.defaultdatatype);
427
428         i=0;
429         while (len < dbuf.dsize) {
430                 driver.dependentfiles = (fstring *)Realloc(driver.dependentfiles,
431                                                          sizeof(fstring)*(i+2));
432                 if (driver.dependentfiles == NULL)
433                         break;
434
435                 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f", 
436                                   &driver.dependentfiles[i]);
437                 i++;
438         }
439         if (driver.dependentfiles != NULL)
440                 fstrcpy(driver.dependentfiles[i], "");
441
442         safe_free(dbuf.dptr);
443
444         if (len != dbuf.dsize) {
445                 if (driver.dependentfiles != NULL)
446                         safe_free(driver.dependentfiles);
447
448                 return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
449         }
450
451         *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
452
453         return 0;
454 }
455
456 /****************************************************************************
457 debugging function, dump at level 6 the struct in the logs
458 ****************************************************************************/
459 static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
460 {
461         uint32 success;
462         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
463         int i;
464         
465         DEBUG(106,("Dumping printer driver at level [%d]\n", level));
466         
467         switch (level)
468         {
469                 case 3: 
470                 {
471                         if (driver.info_3 == NULL)
472                                 success=5;
473                         else {
474                                 info3=driver.info_3;
475                         
476                                 DEBUGADD(106,("version:[%d]\n",         info3->cversion));
477                                 DEBUGADD(106,("name:[%s]\n",            info3->name));
478                                 DEBUGADD(106,("environment:[%s]\n",     info3->environment));
479                                 DEBUGADD(106,("driverpath:[%s]\n",      info3->driverpath));
480                                 DEBUGADD(106,("datafile:[%s]\n",        info3->datafile));
481                                 DEBUGADD(106,("configfile:[%s]\n",      info3->configfile));
482                                 DEBUGADD(106,("helpfile:[%s]\n",        info3->helpfile));
483                                 DEBUGADD(106,("monitorname:[%s]\n",     info3->monitorname));
484                                 DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
485                                 
486                                 for (i=0; info3->dependentfiles &&
487                                           *info3->dependentfiles[i]; i++) {
488                                         DEBUGADD(106,("dependentfile:[%s]\n", 
489                                                       info3->dependentfiles[i]));
490                                 }
491                                 success=0;
492                         }
493                         break;
494                 }
495                 default:
496                         DEBUGADD(1,("Level not implemented\n"));
497                         success=1;
498                         break;
499         }
500         
501         return (success);
502 }
503
504 /****************************************************************************
505 ****************************************************************************/
506 static int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
507 {
508         int len = 0;
509
510         len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
511
512         if (!nt_devmode) return len;
513
514         len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
515                         nt_devmode->devicename,
516                         nt_devmode->formname,
517
518                         nt_devmode->specversion,
519                         nt_devmode->driverversion,
520                         nt_devmode->size,
521                         nt_devmode->driverextra,
522                         nt_devmode->orientation,
523                         nt_devmode->papersize,
524                         nt_devmode->paperlength,
525                         nt_devmode->paperwidth,
526                         nt_devmode->scale,
527                         nt_devmode->copies,
528                         nt_devmode->defaultsource,
529                         nt_devmode->printquality,
530                         nt_devmode->color,
531                         nt_devmode->duplex,
532                         nt_devmode->yresolution,
533                         nt_devmode->ttoption,
534                         nt_devmode->collate,
535                         nt_devmode->logpixels,
536                         
537                         nt_devmode->fields,
538                         nt_devmode->bitsperpel,
539                         nt_devmode->pelswidth,
540                         nt_devmode->pelsheight,
541                         nt_devmode->displayflags,
542                         nt_devmode->displayfrequency,
543                         nt_devmode->icmmethod,
544                         nt_devmode->icmintent,
545                         nt_devmode->mediatype,
546                         nt_devmode->dithertype,
547                         nt_devmode->reserved1,
548                         nt_devmode->reserved2,
549                         nt_devmode->panningwidth,
550                         nt_devmode->panningheight,
551                         nt_devmode->private);
552
553         
554         if (nt_devmode->private) {
555                 len += tdb_pack(buf+len, buflen-len, "B",
556                                 nt_devmode->driverextra,
557                                 nt_devmode->private);
558         }
559
560         DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname));
561
562         return len;
563 }
564
565 /****************************************************************************
566 ****************************************************************************/
567 static int pack_specifics(NT_PRINTER_PARAM *param, char *buf, int buflen)
568 {
569         int len = 0;
570
571         while (param != NULL) {
572                 len += tdb_pack(buf+len, buflen-len, "pfdB",
573                                 param,
574                                 param->value, 
575                                 param->type, 
576                                 param->data_len,
577                                 param->data);
578                 param=param->next;      
579         }
580
581         len += tdb_pack(buf+len, buflen-len, "p", param);
582
583         return len;
584 }
585
586
587 /****************************************************************************
588 delete a printer - this just deletes the printer info file, any open
589 handles are not affected
590 ****************************************************************************/
591 uint32 del_a_printer(char *portname)
592 {
593         pstring key;
594         TDB_DATA kbuf;
595
596         slprintf(key, sizeof(key), "%s%s",
597                  PRINTERS_PREFIX, portname);
598
599         kbuf.dptr=key;
600         kbuf.dsize=strlen(key)+1;
601
602         tdb_delete(tdb, kbuf);
603         return 0;
604 }
605
606 /****************************************************************************
607 ****************************************************************************/
608 static uint32 add_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
609 {
610         pstring key;
611         char *buf;
612         int buflen, len, ret;
613         TDB_DATA kbuf, dbuf;
614         
615         /* 
616          * in addprinter: no servername and the printer is the name
617          * in setprinter: servername is \\server
618          *                and printer is \\server\\printer
619          *
620          * Samba manages only local printers.
621          * we currently don't support things like path=\\other_server\printer
622          */
623         if (info->servername[0]!='\0')
624         {
625                 trim_string(info->printername, info->servername, NULL);
626                 trim_string(info->printername, "\\", NULL);
627                 info->servername[0]='\0';
628         }
629
630         /*
631          * JFM: one day I'll forget.
632          * below that's info->portname because that's the SAMBA sharename
633          * and I made NT 'thinks' it's the portname
634          * the info->sharename is the thing you can name when you add a printer
635          * that's the short-name when you create shared printer for 95/98
636          * So I've made a limitation in SAMBA: you can only have 1 printer model
637          * behind a SAMBA share.
638          */
639
640
641         buf = NULL;
642         buflen = 0;
643
644  again: 
645         len = 0;
646         len += tdb_pack(buf+len, buflen-len, "dddddddddddffffffffff",
647                         info->attributes,
648                         info->priority,
649                         info->default_priority,
650                         info->starttime,
651                         info->untiltime,
652                         info->status,
653                         info->cjobs,
654                         info->averageppm,
655                         info->changeid,
656                         info->c_setprinter,
657                         info->setuptime,
658                         info->servername,
659                         info->printername,
660                         info->sharename,
661                         info->portname,
662                         info->drivername,
663                         info->location,
664                         info->sepfile,
665                         info->printprocessor,
666                         info->datatype,
667                         info->parameters);
668
669         len += pack_devicemode(info->devmode, buf+len, buflen-len);
670         len += pack_specifics(info->specific, buf+len, buflen-len);
671
672         if (buflen != len) {
673                 buf = (char *)Realloc(buf, len);
674                 buflen = len;
675                 goto again;
676         }
677         
678
679         slprintf(key, sizeof(key), "%s%s",
680                  PRINTERS_PREFIX, info->portname);
681
682         kbuf.dptr = key;
683         kbuf.dsize = strlen(key)+1;
684         dbuf.dptr = buf;
685         dbuf.dsize = len;
686
687         ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
688
689         safe_free(buf);
690
691         DEBUG(8,("packed printer [%s] with printprocessor [%s] parameters=[%s] len=%d\n", 
692                  info->portname, info->printprocessor, info->parameters, len));
693
694         return ret;
695 }
696
697
698 /****************************************************************************
699 ****************************************************************************/
700 BOOL add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
701 {
702         NT_PRINTER_PARAM *current;
703         
704         DEBUG(108,("add_a_specific_param\n"));  
705
706         param->next=NULL;
707         
708         if (info_2->specific == NULL)
709         {
710                 info_2->specific=param;
711         }
712         else
713         {
714                 current=info_2->specific;               
715                 while (current->next != NULL) {
716                         current=current->next;
717                 }               
718                 current->next=param;
719         }
720         return (True);
721 }
722
723 /****************************************************************************
724 ****************************************************************************/
725 BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
726 {
727         NT_PRINTER_PARAM *current;
728         NT_PRINTER_PARAM *previous;
729         
730         current=info_2->specific;
731         previous=current;
732         
733         if (current==NULL) return (False);
734         
735         if ( !strcmp(current->value, param->value) && 
736             (strlen(current->value)==strlen(param->value)) ) {
737                 DEBUG(109,("deleting first value\n"));
738                 info_2->specific=current->next;
739                 safe_free(current->data);
740                 safe_free(current);
741                 DEBUG(109,("deleted first value\n"));
742                 return (True);
743         }
744
745         current=previous->next;
746                 
747         while ( current!=NULL ) {
748                 if (!strcmp(current->value, param->value) &&
749                     strlen(current->value)==strlen(param->value) ) {
750                         DEBUG(109,("deleting current value\n"));
751                         previous->next=current->next;
752                         safe_free(current->data);
753                         safe_free(current);
754                         DEBUG(109,("deleted current value\n"));
755                         return(True);
756                 }
757                 
758                 previous=previous->next;
759                 current=current->next;
760         }
761         return (False);
762 }
763
764 /****************************************************************************
765  Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
766 ****************************************************************************/
767 static void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr)
768 {
769         NT_PRINTER_PARAM *param = *param_ptr;
770
771         if(param == NULL)
772                 return;
773
774         DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param->value));
775
776         if(param->data)
777                 safe_free(param->data);
778
779         safe_free(param);
780         *param_ptr = NULL;
781 }
782
783 /****************************************************************************
784  Malloc and return an NT devicemode.
785 ****************************************************************************/
786
787 NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
788 {
789 /*
790  * should I init this ones ???
791         nt_devmode->devicename
792 */
793
794         char adevice[32];
795         NT_DEVICEMODE *nt_devmode = (NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE));
796
797         if (nt_devmode == NULL) {
798                 DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
799                 return NULL;
800         }
801
802         ZERO_STRUCTP(nt_devmode);
803
804         snprintf(adevice, sizeof(adevice), "\\\\%s\\%s", global_myname, default_devicename);
805         fstrcpy(nt_devmode->devicename, adevice);
806         
807         
808         fstrcpy(nt_devmode->formname, "Letter");
809
810         nt_devmode->specversion      = 0x0401;
811         nt_devmode->driverversion    = 0x0400;
812         nt_devmode->size             = 0x00DC;
813         nt_devmode->driverextra      = 0x0000;
814         nt_devmode->fields           = FORMNAME | TTOPTION | PRINTQUALITY | 
815                                        DEFAULTSOURCE | COPIES | SCALE | 
816                                        PAPERSIZE | ORIENTATION;
817         nt_devmode->orientation      = 1;
818         nt_devmode->papersize        = PAPER_LETTER;
819         nt_devmode->paperlength      = 0;
820         nt_devmode->paperwidth       = 0;
821         nt_devmode->scale            = 0x64;
822         nt_devmode->copies           = 01;
823         nt_devmode->defaultsource    = BIN_FORMSOURCE;
824         nt_devmode->printquality     = 0x0258;
825         nt_devmode->color            = COLOR_MONOCHROME;
826         nt_devmode->duplex           = DUP_SIMPLEX;
827         nt_devmode->yresolution      = 0;
828         nt_devmode->ttoption         = TT_SUBDEV;
829         nt_devmode->collate          = COLLATE_FALSE;
830         nt_devmode->icmmethod        = 0;
831         nt_devmode->icmintent        = 0;
832         nt_devmode->mediatype        = 0;
833         nt_devmode->dithertype       = 0;
834
835         /* non utilisés par un driver d'imprimante */
836         nt_devmode->logpixels        = 0;
837         nt_devmode->bitsperpel       = 0;
838         nt_devmode->pelswidth        = 0;
839         nt_devmode->pelsheight       = 0;
840         nt_devmode->displayflags     = 0;
841         nt_devmode->displayfrequency = 0;
842         nt_devmode->reserved1        = 0;
843         nt_devmode->reserved2        = 0;
844         nt_devmode->panningwidth     = 0;
845         nt_devmode->panningheight    = 0;
846         
847         nt_devmode->private=NULL;
848
849         return nt_devmode;
850 }
851
852 /****************************************************************************
853  Deepcopy an NT devicemode.
854 ****************************************************************************/
855
856 NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
857 {
858         NT_DEVICEMODE *new_nt_devicemode = NULL;
859
860         if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
861                 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
862                 return NULL;
863         }
864
865         new_nt_devicemode->private = NULL;
866         if (nt_devicemode->private != NULL) {
867                 if ((new_nt_devicemode->private = memdup(nt_devicemode->private, nt_devicemode->driverextra)) == NULL) {
868                         safe_free(new_nt_devicemode);
869                         DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
870                         return NULL;
871         }
872         }
873
874         return new_nt_devicemode;
875 }
876
877 /****************************************************************************
878  Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
879 ****************************************************************************/
880
881 void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
882 {
883         NT_DEVICEMODE *nt_devmode = *devmode_ptr;
884
885         if(nt_devmode == NULL)
886                 return;
887
888         DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
889
890         if(nt_devmode->private)
891                 safe_free(nt_devmode->private);
892
893         safe_free(nt_devmode);
894         *devmode_ptr = NULL;
895 }
896
897 /****************************************************************************
898  Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
899 ****************************************************************************/
900 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
901 {
902         NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
903         NT_PRINTER_PARAM *param_ptr;
904
905         if(info == NULL)
906                 return;
907
908         DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
909
910         free_nt_devicemode(&info->devmode);
911         free_sec_desc_buf(&info->secdesc_buf);
912
913         for(param_ptr = info->specific; param_ptr; ) {
914                 NT_PRINTER_PARAM *tofree = param_ptr;
915
916                 param_ptr = param_ptr->next;
917                 free_nt_printer_param(&tofree);
918         }
919
920         safe_free(*info_ptr);
921         *info_ptr = NULL;
922 }
923
924
925 /****************************************************************************
926 ****************************************************************************/
927 static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
928 {
929         int len = 0;
930         NT_DEVICEMODE devmode;
931
932         ZERO_STRUCT(devmode);
933
934         len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
935
936         if (!*nt_devmode) return len;
937
938         len += tdb_unpack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
939                           devmode.devicename,
940                           devmode.formname,
941
942                           &devmode.specversion,
943                           &devmode.driverversion,
944                           &devmode.size,
945                           &devmode.driverextra,
946                           &devmode.orientation,
947                           &devmode.papersize,
948                           &devmode.paperlength,
949                           &devmode.paperwidth,
950                           &devmode.scale,
951                           &devmode.copies,
952                           &devmode.defaultsource,
953                           &devmode.printquality,
954                           &devmode.color,
955                           &devmode.duplex,
956                           &devmode.yresolution,
957                           &devmode.ttoption,
958                           &devmode.collate,
959                           &devmode.logpixels,
960                           
961                           &devmode.fields,
962                           &devmode.bitsperpel,
963                           &devmode.pelswidth,
964                           &devmode.pelsheight,
965                           &devmode.displayflags,
966                           &devmode.displayfrequency,
967                           &devmode.icmmethod,
968                           &devmode.icmintent,
969                           &devmode.mediatype,
970                           &devmode.dithertype,
971                           &devmode.reserved1,
972                           &devmode.reserved2,
973                           &devmode.panningwidth,
974                           &devmode.panningheight,
975                           &devmode.private);
976         
977         if (devmode.private) {
978                 devmode.private = (uint8 *)malloc(devmode.driverextra);
979                 if (!devmode.private) return 2;
980                 len += tdb_unpack(buf+len, buflen-len, "B",
981                                   devmode.driverextra,
982                                   devmode.private);
983         }
984
985         *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
986
987         DEBUG(8,("Unpacked devicemode [%s]\n", devmode.formname));
988
989         return len;
990 }
991
992 /****************************************************************************
993 ****************************************************************************/
994 static int unpack_specifics(NT_PRINTER_PARAM **list, char *buf, int buflen)
995 {
996         int len = 0;
997         NT_PRINTER_PARAM param, *p;
998
999         *list = NULL;
1000
1001         while (1) {
1002                 len += tdb_unpack(buf+len, buflen-len, "p", &p);
1003                 if (!p) break;
1004
1005                 len += tdb_unpack(buf+len, buflen-len, "fdB",
1006                                   param.value, 
1007                                   &param.type, 
1008                                   &param.data_len,
1009                                   &param.data);
1010                 param.next = *list;
1011                 *list = memdup(&param, sizeof(param));
1012         }
1013
1014         return len;
1015 }
1016
1017
1018 /****************************************************************************
1019 get a default printer info 2 struct
1020 ****************************************************************************/
1021 static uint32 get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
1022 {
1023         extern pstring global_myname;
1024         int snum;
1025         NT_PRINTER_INFO_LEVEL_2 info;
1026
1027         ZERO_STRUCT(info);
1028
1029         snum = lp_servicenumber(sharename);
1030
1031         fstrcpy(info.servername, global_myname);
1032         fstrcpy(info.printername, sharename);
1033         fstrcpy(info.portname, sharename);
1034         fstrcpy(info.drivername, lp_printerdriver(snum));
1035         fstrcpy(info.printprocessor, "winprint");
1036         fstrcpy(info.datatype, "RAW");
1037
1038         info.attributes = PRINTER_ATTRIBUTE_SHARED   \
1039                          | PRINTER_ATTRIBUTE_LOCAL  \
1040                          | PRINTER_ATTRIBUTE_RAW_ONLY ;            /* attributes */
1041
1042         info.starttime = 0; /* Minutes since 12:00am GMT */
1043         info.untiltime = 0; /* Minutes since 12:00am GMT */
1044         info.priority = 1;
1045         info.default_priority = 1;
1046
1047         if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
1048                 goto fail;
1049
1050         if (!nt_printing_getsec(sharename, &info.secdesc_buf))
1051                 goto fail;
1052
1053         *info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
1054         if (! *info_ptr) {
1055                 DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
1056                 goto fail;
1057         }
1058
1059         return (0);     
1060
1061   fail:
1062
1063         if (info.devmode)
1064                 free_nt_devicemode(&info.devmode);
1065         if (info.secdesc_buf)
1066                 free_sec_desc_buf(&info.secdesc_buf);
1067         return 2;
1068 }
1069
1070 /****************************************************************************
1071 ****************************************************************************/
1072 static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
1073 {
1074         pstring key;
1075         NT_PRINTER_INFO_LEVEL_2 info;
1076         int len = 0;
1077         TDB_DATA kbuf, dbuf;
1078                 
1079         ZERO_STRUCT(info);
1080
1081         slprintf(key, sizeof(key), "%s%s",
1082                  PRINTERS_PREFIX, sharename);
1083
1084         kbuf.dptr = key;
1085         kbuf.dsize = strlen(key)+1;
1086
1087         dbuf = tdb_fetch(tdb, kbuf);
1088 #if 1 /* JRATEST */
1089         if (!dbuf.dptr) return get_a_printer_2_default(info_ptr, sharename);
1090 #else
1091         if (!dbuf.dptr) return 1;
1092 #endif
1093
1094         len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddffffffffff",
1095                         &info.attributes,
1096                         &info.priority,
1097                         &info.default_priority,
1098                         &info.starttime,
1099                         &info.untiltime,
1100                         &info.status,
1101                         &info.cjobs,
1102                         &info.averageppm,
1103                         &info.changeid,
1104                         &info.c_setprinter,
1105                         &info.setuptime,
1106                         info.servername,
1107                         info.printername,
1108                         info.sharename,
1109                         info.portname,
1110                         info.drivername,
1111                         info.location,
1112                         info.sepfile,
1113                         info.printprocessor,
1114                         info.datatype,
1115                         info.parameters);
1116
1117         info.attributes |= PRINTER_ATTRIBUTE_RAW_ONLY; /* Samba has to have raw drivers. */
1118
1119         len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
1120         len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
1121
1122 #if 1 /* JRATEST */
1123         nt_printing_getsec(sharename, &info.secdesc_buf);
1124 #endif /* JRATEST */
1125
1126         fstrcpy(info.sharename, "");
1127
1128         safe_free(dbuf.dptr);
1129         *info_ptr=memdup(&info, sizeof(info));
1130
1131         DEBUG(9,("Unpacked printprocessor for [%s] of [%s]\n",
1132                  sharename, info.printprocessor));
1133
1134         
1135         return 0;       
1136 }
1137
1138 /****************************************************************************
1139 debugging function, dump at level 6 the struct in the logs
1140 ****************************************************************************/
1141 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1142 {
1143         uint32 success;
1144         NT_PRINTER_INFO_LEVEL_2 *info2;
1145         
1146         DEBUG(106,("Dumping printer at level [%d]\n", level));
1147         
1148         switch (level)
1149         {
1150                 case 2: 
1151                 {
1152                         if (printer.info_2 == NULL)
1153                                 success=5;
1154                         else
1155                         {
1156                                 info2=printer.info_2;
1157                         
1158                                 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
1159                                 DEBUGADD(106,("priority:[%d]\n", info2->priority));
1160                                 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
1161                                 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
1162                                 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
1163                                 DEBUGADD(106,("status:[%d]\n", info2->status));
1164                                 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
1165                                 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
1166                                 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
1167                                 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
1168                                 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
1169
1170                                 DEBUGADD(106,("servername:[%s]\n", info2->servername));
1171                                 DEBUGADD(106,("printername:[%s]\n", info2->printername));
1172                                 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
1173                                 DEBUGADD(106,("portname:[%s]\n", info2->portname));
1174                                 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
1175                                 DEBUGADD(106,("location:[%s]\n", info2->location));
1176                                 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
1177                                 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
1178                                 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
1179                                 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
1180                                 success=0;
1181                         }
1182                         break;
1183                 }
1184                 default:
1185                         DEBUGADD(1,("Level not implemented\n"));
1186                         success=1;
1187                         break;
1188         }
1189         
1190         return (success);
1191 }
1192
1193 /*
1194  * The function below are the high level ones.
1195  * only those ones must be called from the spoolss code.
1196  * JFM.
1197  */
1198
1199
1200 /****************************************************************************
1201 ****************************************************************************/
1202 uint32 add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1203 {
1204         uint32 success;
1205         
1206         dump_a_printer(printer, level); 
1207         
1208         switch (level)
1209         {
1210                 case 2: 
1211                 {
1212                         success=add_a_printer_2(printer.info_2);
1213                         break;
1214                 }
1215                 default:
1216                         success=1;
1217                         break;
1218         }
1219         
1220         return (success);
1221 }
1222
1223 /****************************************************************************
1224  Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
1225 ****************************************************************************/
1226
1227 uint32 get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename)
1228 {
1229         uint32 success;
1230         NT_PRINTER_INFO_LEVEL *printer = NULL;
1231         
1232         *pp_printer = NULL;
1233
1234         DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
1235
1236         switch (level)
1237         {
1238                 case 2: 
1239                 {
1240                         if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
1241                                 DEBUG(0,("get_a_printer: malloc fail.\n"));
1242                                 return 1;
1243                         }
1244                         ZERO_STRUCTP(printer);
1245                         success=get_a_printer_2(&printer->info_2, sharename);
1246                         if (success == 0) {
1247                                 dump_a_printer(*printer, level);
1248                                 *pp_printer = printer;
1249                         } else {
1250                                 safe_free(printer);
1251                         }
1252                         break;
1253                 }
1254                 default:
1255                         success=1;
1256                         break;
1257         }
1258         
1259         DEBUG(10,("get_a_printer: [%s] level %u returning %u\n", sharename, (unsigned int)level, (unsigned int)success));
1260
1261         return (success);
1262 }
1263
1264 /****************************************************************************
1265  Deletes a NT_PRINTER_INFO_LEVEL struct.
1266 ****************************************************************************/
1267
1268 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
1269 {
1270         uint32 success;
1271         NT_PRINTER_INFO_LEVEL *printer = *pp_printer;
1272
1273         DEBUG(104,("freeing a printer at level [%d]\n", level));
1274
1275         if (printer == NULL)
1276                 return 0;
1277         
1278         switch (level)
1279         {
1280                 case 2: 
1281                 {
1282                         if (printer->info_2 != NULL)
1283                         {
1284                                 free_nt_printer_info_level_2(&printer->info_2);
1285                                 success=0;
1286                         }
1287                         else
1288                         {
1289                                 success=4;
1290                         }
1291                         break;
1292                 }
1293                 default:
1294                         success=1;
1295                         break;
1296         }
1297
1298         safe_free(printer);
1299         *pp_printer = NULL;
1300         return (success);
1301 }
1302
1303 /****************************************************************************
1304 ****************************************************************************/
1305 uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1306 {
1307         uint32 success;
1308         DEBUG(104,("adding a printer at level [%d]\n", level));
1309         dump_a_printer_driver(driver, level);
1310         
1311         switch (level)
1312         {
1313                 case 3: 
1314                 {
1315                         success=add_a_printer_driver_3(driver.info_3);
1316                         break;
1317                 }
1318
1319                 case 6: 
1320                 {
1321                         success=add_a_printer_driver_6(driver.info_6);
1322                         break;
1323                 }
1324                 default:
1325                         success=1;
1326                         break;
1327         }
1328         
1329         return (success);
1330 }
1331 /****************************************************************************
1332 ****************************************************************************/
1333 uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level, 
1334                             fstring printername, fstring architecture)
1335 {
1336         uint32 success;
1337         
1338         switch (level)
1339         {
1340                 case 3: 
1341                 {
1342                         success=get_a_printer_driver_3(&(driver->info_3), 
1343                                                        printername,
1344                                                        architecture);
1345                         break;
1346                 }
1347                 default:
1348                         success=1;
1349                         break;
1350         }
1351         
1352         if (success == 0) dump_a_printer_driver(*driver, level);
1353         return (success);
1354 }
1355
1356 /****************************************************************************
1357 ****************************************************************************/
1358 uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1359 {
1360         uint32 success;
1361         
1362         switch (level)
1363         {
1364                 case 3: 
1365                 {
1366                         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1367                         if (driver.info_3 != NULL)
1368                         {
1369                                 info3=driver.info_3;
1370                                 safe_free(info3->dependentfiles);
1371                                 ZERO_STRUCTP(info3);
1372                                 safe_free(info3);
1373                                 success=0;
1374                         }
1375                         else
1376                         {
1377                                 success=4;
1378                         }
1379                         break;
1380                 }
1381                 case 6: 
1382                 {
1383                         NT_PRINTER_DRIVER_INFO_LEVEL_6 *info6;
1384                         if (driver.info_6 != NULL)
1385                         {
1386                                 info6=driver.info_6;
1387                                 safe_free(info6->dependentfiles);
1388                                 safe_free(info6->previousnames);
1389                                 ZERO_STRUCTP(info6);
1390                                 safe_free(info6);
1391                                 success=0;
1392                         }
1393                         else
1394                         {
1395                                 success=4;
1396                         }
1397                         break;
1398                 }
1399                 default:
1400                         success=1;
1401                         break;
1402         }
1403         return (success);
1404 }
1405
1406 /****************************************************************************
1407 ****************************************************************************/
1408 BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
1409                                  fstring value, uint8 **data, uint32 *type, uint32 *len)
1410 {
1411         /* right now that's enough ! */ 
1412         NT_PRINTER_PARAM *param;
1413         int i=0;
1414         
1415         param=printer.info_2->specific;
1416         
1417         while (param != NULL && i <= param_index)
1418         {
1419                 param=param->next;
1420                 i++;
1421         }
1422         
1423         if (param == NULL)
1424                 return False;
1425
1426         /* exited because it exist */
1427         *type=param->type;              
1428         StrnCpy(value, param->value, sizeof(fstring)-1);
1429         *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
1430         if(*data == NULL)
1431                 return False;
1432         memcpy(*data, param->data, param->data_len);
1433         *len=param->data_len;
1434         return True;
1435 }
1436
1437 /****************************************************************************
1438 ****************************************************************************/
1439 BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level, 
1440                         fstring value, uint8 **data, uint32 *type, uint32 *len)
1441 {
1442         /* right now that's enough ! */ 
1443         NT_PRINTER_PARAM *param;
1444         
1445         DEBUG(105, ("get_specific_param\n"));
1446         
1447         param=printer.info_2->specific;
1448                 
1449         while (param != NULL)
1450         {
1451                 if ( !strcmp(value, param->value) 
1452                     && strlen(value)==strlen(param->value))
1453                         break;
1454                         
1455                 param=param->next;
1456         }
1457         
1458         DEBUG(106, ("found one param\n"));
1459         if (param != NULL)
1460         {
1461                 /* exited because it exist */
1462                 *type=param->type;      
1463                 
1464                 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
1465                 if(*data == NULL)
1466                         return False;
1467                 memcpy(*data, param->data, param->data_len);
1468                 *len=param->data_len;
1469
1470                 DEBUG(106, ("exit of get_specific_param:true\n"));
1471                 return (True);
1472         }
1473         DEBUG(106, ("exit of get_specific_param:false\n"));
1474         return (False);
1475 }
1476
1477
1478 /****************************************************************************
1479 store a security desc for a printer
1480 ****************************************************************************/
1481 uint32 nt_printing_setsec(char *printername, struct current_user *user,
1482                           SEC_DESC_BUF *secdesc_ctr)
1483 {
1484         SEC_DESC_BUF *new_secdesc_ctr = NULL;
1485         SEC_DESC_BUF *old_secdesc_ctr = NULL;
1486         prs_struct ps;
1487         fstring key;
1488         uint32 acc_granted, status;
1489
1490         /* Get old security descriptor */
1491
1492         if (!nt_printing_getsec(printername, &old_secdesc_ctr)) {
1493                 DEBUG(3, ("could not get old security descriptor for "
1494                           "printer %s", printername));
1495                 return ERROR_INVALID_FUNCTION;
1496         }
1497
1498         /* Check the user has permissions to change the security
1499            descriptor.  By experimentation with two NT machines, the user
1500            requires Full Access to the printer to change security
1501            information. */ 
1502
1503         if (!se_access_check(old_secdesc_ctr->sec, user->uid, user->gid,
1504                              user->ngroups, user->groups, 
1505                              PRINTER_ACE_FULL_CONTROL, &acc_granted,
1506                              &status)) {
1507                 DEBUG(3, ("security descriptor change denied by existing "
1508                           "security descriptor\n"));
1509                 free_sec_desc_buf(&old_secdesc_ctr);
1510                 return status;
1511         }
1512
1513         /* The old owner and group sids of the security descriptor are not
1514            present when new ACEs are added or removed by changing printer
1515            permissions through NT.  If they are NULL in the new security
1516            descriptor then copy them over from the old one. */
1517
1518         if (!secdesc_ctr->sec->owner_sid || !secdesc_ctr->sec->grp_sid) {
1519                 DOM_SID *owner_sid, *group_sid;
1520                 SEC_DESC *psd = NULL;
1521                 size_t size;
1522
1523                 /* Pick out correct owner and group sids */
1524
1525                 owner_sid = secdesc_ctr->sec->owner_sid ?
1526                         secdesc_ctr->sec->owner_sid :
1527                         old_secdesc_ctr->sec->owner_sid;
1528
1529                 group_sid = secdesc_ctr->sec->grp_sid ?
1530                         secdesc_ctr->sec->grp_sid :
1531                         old_secdesc_ctr->sec->grp_sid;
1532
1533                 /* Make a deep copy of the security descriptor */
1534
1535                 psd = make_sec_desc(secdesc_ctr->sec->revision,
1536                                     secdesc_ctr->sec->type,
1537                                     owner_sid, group_sid,
1538                                     secdesc_ctr->sec->sacl,
1539                                     secdesc_ctr->sec->dacl,
1540                                     &size);
1541
1542                 new_secdesc_ctr = make_sec_desc_buf(size, psd);
1543
1544                 /* Free up memory */
1545
1546                 free_sec_desc(&psd);
1547         }
1548
1549         if (!new_secdesc_ctr) {
1550                 new_secdesc_ctr = secdesc_ctr;
1551         }
1552
1553         /* Store the security descriptor in a tdb */
1554
1555         prs_init(&ps, (uint32)sec_desc_size(new_secdesc_ctr->sec) + 
1556                  sizeof(SEC_DESC_BUF), 4, MARSHALL);
1557
1558         if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr, 
1559                              &ps, 1)) {
1560                 status = ERROR_INVALID_FUNCTION;
1561                 goto out;
1562         }
1563
1564         slprintf(key, sizeof(key), "SECDESC/%s", printername);
1565
1566         if (tdb_prs_store(tdb, key, &ps)==0) {
1567                 status = 0;
1568         } else {
1569                 DEBUG(1,("Failed to store secdesc for %s\n", printername));
1570                 status = ERROR_INVALID_FUNCTION;
1571         }
1572
1573         /* Free mallocated memory */
1574
1575  out:
1576         free_sec_desc_buf(&old_secdesc_ctr);
1577
1578         if (new_secdesc_ctr != secdesc_ctr) {
1579                 free_sec_desc_buf(&new_secdesc_ctr);
1580         }
1581
1582         prs_mem_free(&ps);
1583         return status;
1584 }
1585
1586 /* Call winbindd to convert a name to a sid */
1587
1588 BOOL winbind_lookup_name(char *name, DOM_SID *sid, uint8 *name_type)
1589 {
1590         struct winbindd_request request;
1591         struct winbindd_response response;
1592         enum nss_status result;
1593         
1594         if (!sid || !name_type) return False;
1595
1596         /* Send off request */
1597
1598         ZERO_STRUCT(request);
1599         ZERO_STRUCT(response);
1600
1601         fstrcpy(request.data.name, name);
1602         if ((result = winbindd_request(WINBINDD_LOOKUPNAME, &request, 
1603                                        &response)) == NSS_STATUS_SUCCESS) {
1604                 string_to_sid(sid, response.data.sid.sid);
1605                 *name_type = response.data.sid.type;
1606         }
1607
1608         return result == NSS_STATUS_SUCCESS;
1609 }
1610
1611 /****************************************************************************
1612  Construct a default security descriptor buffer for a printer.
1613 ****************************************************************************/
1614
1615 static SEC_DESC_BUF *construct_default_printer_sdb(void)
1616 {
1617         extern DOM_SID global_sid_World; 
1618         SEC_ACE ace;
1619         SEC_ACCESS sa;
1620         SEC_ACL *psa = NULL;
1621         SEC_DESC_BUF *sdb = NULL;
1622         SEC_DESC *psd = NULL;
1623         DOM_SID owner_sid;
1624         size_t sd_size;
1625         uint8 name_type;
1626
1627         /* Create an ACE where Everyone is allowed to print */
1628
1629         init_sec_access(&sa, PRINTER_ACE_PRINT);
1630         init_sec_ace(&ace, &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
1631                      sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
1632
1633         /* Make the security descriptor owned by the Administrators group
1634            on the PDC of the domain. */
1635
1636         if (!winbind_lookup_name("Administrator", &owner_sid, &name_type)) {
1637                 return NULL;  /* Doh */
1638         }
1639
1640         
1641
1642         /* The ACL revision number in rpc_secdesc.h differs from the one
1643            created by NT when setting ACE entries in printer
1644            descriptors.  NT4 complains about the property being edited by a
1645            NT5 machine. */
1646
1647 #define NT4_ACL_REVISION 0x2
1648
1649         if ((psa = make_sec_acl(NT4_ACL_REVISION, 1, &ace)) != NULL) {
1650                 psd = make_sec_desc(SEC_DESC_REVISION, 
1651                                     SEC_DESC_SELF_RELATIVE | 
1652                                     SEC_DESC_DACL_PRESENT,
1653                                     &owner_sid, NULL,
1654                                     NULL, psa, &sd_size);
1655                 free_sec_acl(&psa);
1656         }
1657
1658         if (!psd) {
1659                 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
1660                 return NULL;
1661         }
1662
1663         sdb = make_sec_desc_buf(sd_size, psd);
1664
1665         DEBUG(4,("construct_default_printer_sdb: size = %u.\n", 
1666                  (unsigned int)sd_size));
1667
1668         free_sec_desc(&psd);
1669         return sdb;
1670 }
1671
1672 /****************************************************************************
1673  Get a security desc for a printer.
1674 ****************************************************************************/
1675
1676 BOOL nt_printing_getsec(char *printername, SEC_DESC_BUF **secdesc_ctr)
1677 {
1678         prs_struct ps;
1679         fstring key;
1680
1681         slprintf(key, sizeof(key), "SECDESC/%s", printername);
1682
1683         if (tdb_prs_fetch(tdb, key, &ps)!=0 ||
1684             !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
1685
1686                 DEBUG(4,("using default secdesc for %s\n", printername));
1687
1688                 if (!(*secdesc_ctr = construct_default_printer_sdb()))
1689                         return False;
1690
1691                 return True;
1692         }
1693
1694         prs_mem_free(&ps);
1695         return True;
1696 }
1697
1698 /* error code:
1699         0: everything OK
1700         1: level not implemented
1701         2: file doesn't exist
1702         3: can't allocate memory
1703         4: can't free memory
1704         5: non existant struct
1705 */
1706
1707 /*
1708         A printer and a printer driver are 2 different things.
1709         NT manages them separatelly, Samba does the same.
1710         Why ? Simply because it's easier and it makes sense !
1711         
1712         Now explanation: You have 3 printers behind your samba server,
1713         2 of them are the same make and model (laser A and B). But laser B 
1714         has an 3000 sheet feeder and laser A doesn't such an option.
1715         Your third printer is an old dot-matrix model for the accounting :-).
1716         
1717         If the /usr/local/samba/lib directory (default dir), you will have
1718         5 files to describe all of this.
1719         
1720         3 files for the printers (1 by printer):
1721                 NTprinter_laser A
1722                 NTprinter_laser B
1723                 NTprinter_accounting
1724         2 files for the drivers (1 for the laser and 1 for the dot matrix)
1725                 NTdriver_printer model X
1726                 NTdriver_printer model Y
1727
1728 jfm: I should use this comment for the text file to explain 
1729         same thing for the forms BTW.
1730         Je devrais mettre mes commentaires en francais, ca serait mieux :-)
1731
1732 */
1733
1734 /* Check a user has permissions to perform the given operation */
1735
1736 BOOL print_access_check(struct current_user *user, int snum,
1737                         uint32 required_access)
1738 {
1739         SEC_DESC_BUF *secdesc = NULL;
1740         uint32 access_granted, status;
1741         BOOL result;
1742         char *pname;
1743         int i;
1744         
1745         /* Get printer name */
1746
1747         pname = PRINTERNAME(snum);
1748         if (!pname || !*pname) pname = SERVICE(snum);
1749
1750         /* Get printer security descriptor */
1751
1752         nt_printing_getsec(pname, &secdesc);
1753
1754         /* The ACE for Full Control in a printer security descriptor
1755            doesn't seem to map properly to the access checking model.  For
1756            it to work properly it should be the logical OR of all the other
1757            values, i.e PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT.
1758            This would cause the access check to simply fall out when we
1759            check against any subset of these bits.  To get things to work,
1760            change every ACE mask of PRINTER_ACE_FULL_CONTROL to 
1761            PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT before
1762            performing the access check.  I'm sure there is a better way to
1763            do this! */
1764
1765         if (secdesc && secdesc->sec && secdesc->sec->dacl &&
1766             secdesc->sec->dacl->ace) {
1767                 for(i = 0; i < secdesc->sec->dacl->num_aces; i++) {
1768                         if (secdesc->sec->dacl->ace[i].info.mask ==
1769                             PRINTER_ACE_FULL_CONTROL) {
1770                                 secdesc->sec->dacl->ace[i].info.mask =
1771                                         PRINTER_ACE_MANAGE_DOCUMENTS | 
1772                                         PRINTER_ACE_PRINT;
1773                         }
1774                 }
1775         }
1776
1777         /* Check access */
1778
1779         result = se_access_check(secdesc->sec, user->uid, user->gid,
1780                                  user->ngroups, user->groups,
1781                                  required_access, &access_granted, &status);
1782
1783         DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE"));
1784
1785         /* Free mallocated memory */
1786
1787         free_sec_desc_buf(&secdesc);
1788
1789         return result;
1790 }