7df1aaf405aba2a2a72d66f27e922cefb570f06f
[ira/wip.git] / source3 / 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
27 static TDB_CONTEXT *tdb; /* used for driver files */
28
29 #define FORMS_PREFIX "FORMS/"
30 #define DRIVERS_PREFIX "DRIVERS/"
31 #define PRINTERS_PREFIX "PRINTERS/"
32
33 #define DATABASE_VERSION 1
34
35 /****************************************************************************
36 open the NT printing tdb
37 ****************************************************************************/
38 BOOL nt_printing_init(void)
39 {
40         static pid_t local_pid;
41
42         if (tdb && local_pid == sys_getpid()) return True;
43         tdb = tdb_open(lock_path("ntdrivers.tdb"), 0, 0, O_RDWR|O_CREAT, 0600);
44         if (!tdb) {
45                 DEBUG(0,("Failed to open nt drivers database\n"));
46                 return False;
47         }
48
49         local_pid = sys_getpid();
50
51         /* handle a Samba upgrade */
52         tdb_writelock(tdb);
53         if (tdb_fetch_int(tdb, "INFO/version") != DATABASE_VERSION) {
54                 tdb_traverse(tdb, (tdb_traverse_func)tdb_delete, NULL);
55                 tdb_store_int(tdb, "INFO/version", DATABASE_VERSION);
56         }
57         tdb_writeunlock(tdb);
58
59         return True;
60 }
61
62   
63 /****************************************************************************
64 get a form struct list
65 ****************************************************************************/
66 int get_ntforms(nt_forms_struct **list)
67 {
68         TDB_DATA kbuf, newkey, dbuf;
69         nt_forms_struct form;
70         int ret;
71         int n = 0;
72
73         for (kbuf = tdb_firstkey(tdb); 
74              kbuf.dptr; 
75              newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf=newkey) {
76                 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0) continue;
77                 
78                 dbuf = tdb_fetch(tdb, kbuf);
79                 if (!dbuf.dptr) continue;
80
81                 fstrcpy(form.name, kbuf.dptr+strlen(FORMS_PREFIX));
82                 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddddddd",
83                                  &form.flag, &form.width, &form.length, &form.left,
84                                  &form.top, &form.right, &form.bottom);
85                 free(dbuf.dptr);
86                 if (ret != dbuf.dsize) continue;
87
88                 *list = Realloc(*list, sizeof(nt_forms_struct)*(n+1));
89                 (*list)[n] = form;
90                 n++;
91         }
92
93         return n;
94 }
95
96 /****************************************************************************
97 write a form struct list
98 ****************************************************************************/
99 int write_ntforms(nt_forms_struct **list, int number)
100 {
101         pstring buf, key;
102         int len;
103         TDB_DATA kbuf,dbuf;
104         int i;
105
106         for (i=0;i<number;i++) {
107                 len = tdb_pack(buf, sizeof(buf), "ddddddd", 
108                                (*list)[i].flag, (*list)[i].width, (*list)[i].length,
109                                (*list)[i].left, (*list)[i].top, (*list)[i].right, 
110                                (*list)[i].bottom);
111                 if (len > sizeof(buf)) break;
112                 slprintf(key, sizeof(key), "%s/%s", FORMS_PREFIX, (*list)[i].name);
113                 kbuf.dsize = strlen(key)+1;
114                 kbuf.dptr = key;
115                 dbuf.dsize = len;
116                 dbuf.dptr = buf;
117                 if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) break;
118        }
119
120        return i;
121 }
122
123 /****************************************************************************
124 add a form struct at the end of the list
125 ****************************************************************************/
126 BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
127 {
128         int n=0;
129         BOOL update;
130         fstring form_name;
131
132         /* 
133          * NT tries to add forms even when 
134          * they are already in the base
135          * only update the values if already present
136          */
137
138         update=False;
139         
140         unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
141         for (n=0; n<*count && update==False; n++)
142         {
143                 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
144                 {
145                         DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
146                         update=True;
147                 }
148         }
149
150         if (update==False)
151         {
152                 if((*list=Realloc(*list, (n+1)*sizeof(nt_forms_struct))) == NULL)
153                         return False;
154                 unistr2_to_ascii((*list)[n].name, &(form->name), sizeof((*list)[n].name)-1);
155                 (*count)++;
156         }
157         
158         (*list)[n].flag=form->flags;
159         (*list)[n].width=form->size_x;
160         (*list)[n].length=form->size_y;
161         (*list)[n].left=form->left;
162         (*list)[n].top=form->top;
163         (*list)[n].right=form->right;
164         (*list)[n].bottom=form->bottom;
165
166         return True;
167 }
168
169 /****************************************************************************
170 update a form struct 
171 ****************************************************************************/
172 void update_a_form(nt_forms_struct **list, const FORM *form, int count)
173 {
174         int n=0;
175         fstring form_name;
176         unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
177
178         DEBUG(106, ("[%s]\n", form_name));
179         for (n=0; n<count; n++)
180         {
181                 DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
182                 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
183                         break;
184         }
185
186         if (n==count) return;
187
188         (*list)[n].flag=form->flags;
189         (*list)[n].width=form->size_x;
190         (*list)[n].length=form->size_y;
191         (*list)[n].left=form->left;
192         (*list)[n].top=form->top;
193         (*list)[n].right=form->right;
194         (*list)[n].bottom=form->bottom;
195 }
196  
197 /****************************************************************************
198 get the nt drivers list
199
200 traverse the database and look-up the matching names
201 ****************************************************************************/
202 int get_ntdrivers(fstring **list, char *architecture)
203 {
204         int total=0;
205         fstring short_archi;
206         pstring key;
207         TDB_DATA kbuf, newkey;
208
209         get_short_archi(short_archi, architecture);
210         slprintf(key, sizeof(key), "%s/%s/", DRIVERS_PREFIX, short_archi);
211
212         for (kbuf = tdb_firstkey(tdb); 
213              kbuf.dptr; 
214              newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf=newkey) {
215                 if (strncmp(kbuf.dptr, key, strlen(key)) != 0) continue;
216                 
217                 if((*list = Realloc(*list, sizeof(fstring)*(total+1))) == NULL)
218                         return -1;
219
220                 fstrcpy((*list)[total], kbuf.dptr+strlen(key));
221                 total++;
222         }
223
224         return(total);
225 }
226
227 /****************************************************************************
228 function to do the mapping between the long architecture name and
229 the short one.
230 ****************************************************************************/
231 void get_short_archi(char *short_archi, char *long_archi)
232 {
233         struct table {
234                 char *long_archi;
235                 char *short_archi;
236         };
237         
238         struct table archi_table[]=
239         {
240                 {"Windows 4.0",          "WIN40"    },
241                 {"Windows NT x86",       "W32X86"   },
242                 {"Windows NT R4000",     "W32mips"  },
243                 {"Windows NT Alpha_AXP", "W32alpha" },
244                 {"Windows NT PowerPC",   "W32ppc"   },
245                 {NULL,                   ""         }
246         };
247         
248         int i=-1;
249
250         DEBUG(107,("Getting architecture dependant directory\n"));
251         do {
252                 i++;
253         } while ( (archi_table[i].long_archi!=NULL ) && strncmp(long_archi, archi_table[i].long_archi, strlen(long_archi)) );
254
255         if (archi_table[i].long_archi==NULL)
256         {
257                 DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
258         }
259         StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
260
261         DEBUGADD(108,("index: [%d]\n", i));
262         DEBUGADD(108,("long architecture: [%s]\n", long_archi));
263         DEBUGADD(108,("short architecture: [%s]\n", short_archi));
264 }
265
266 /****************************************************************************
267 ****************************************************************************/
268 static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
269 {
270         int len, buflen;
271         fstring architecture;
272         pstring key;
273         char *buf;
274         int i, ret;
275         TDB_DATA kbuf, dbuf;
276
277         get_short_archi(architecture, driver->environment);
278         slprintf(key, sizeof(key), "%s/%s/%s", DRIVERS_PREFIX, architecture, driver->name);
279
280         /*
281          * cversion must be 2.
282          * when adding a printer ON the SERVER
283          * rpcAddPrinterDriver defines it to zero
284          * which is wrong !!!
285          *
286          * JFM, 4/14/99
287          */
288         driver->cversion=2;
289         
290         buf = NULL;
291         len = buflen = 0;
292
293  again:
294         len = 0;
295         len += tdb_pack(buf+len, buflen-len, "dffffffff", 
296                         driver->cversion,
297                         driver->name,
298                         driver->environment,
299                         driver->driverpath,
300                         driver->datafile,
301                         driver->configfile,
302                         driver->helpfile,
303                         driver->monitorname,
304                         driver->defaultdatatype);
305         
306         if (driver->dependentfiles) {
307                 for (i=0; *driver->dependentfiles[i]; i++) {
308                         len += tdb_pack(buf+len, buflen-len, "f", 
309                                         driver->dependentfiles[i]);
310                 }
311         }
312
313         if (len != buflen) {
314                 buf = (char *)Realloc(buf, len);
315                 buflen = len;
316                 goto again;
317         }
318
319
320         kbuf.dptr = key;
321         kbuf.dsize = strlen(key)+1;
322         dbuf.dptr = buf;
323         dbuf.dsize = len;
324         
325         ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
326
327         free(buf);
328         return ret;
329 }
330
331 /****************************************************************************
332 ****************************************************************************/
333 static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
334 {
335         NT_PRINTER_DRIVER_INFO_LEVEL_3 info3;
336
337         info3.cversion = driver->version;
338         fstrcpy(info3.environment,driver->environment);
339         fstrcpy(info3.driverpath,driver->driverpath);
340         fstrcpy(info3.datafile,driver->datafile);
341         fstrcpy(info3.configfile,driver->configfile);
342         fstrcpy(info3.helpfile,driver->helpfile);
343         fstrcpy(info3.monitorname,driver->monitorname);
344         fstrcpy(info3.defaultdatatype,driver->defaultdatatype);
345         info3.dependentfiles = driver->dependentfiles;
346
347         return add_a_printer_driver_3(&info3);
348 }
349
350
351 /****************************************************************************
352 ****************************************************************************/
353 static uint32 get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
354 {
355         NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
356         int snum;
357
358         ZERO_STRUCT(info);
359
360         snum = lp_servicenumber(in_prt);
361
362         fstrcpy(info.name, lp_printerdriver(snum));
363         fstrcpy(info.defaultdatatype, "RAW");
364         
365         info.dependentfiles=(fstring *)malloc(sizeof(fstring));
366         fstrcpy(info.dependentfiles[0], "");
367
368         *info_ptr = memdup(&info, sizeof(info));
369         
370         return 0;       
371 }
372
373 /****************************************************************************
374 ****************************************************************************/
375 static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
376 {
377         NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
378         TDB_DATA kbuf, dbuf;
379         fstring architecture;
380         int len = 0;
381         int i;
382         pstring key;
383
384         ZERO_STRUCT(driver);
385
386         get_short_archi(architecture, in_arch);
387         slprintf(key, sizeof(key), "%s/%s/%s", DRIVERS_PREFIX, architecture, in_prt);
388
389         kbuf.dptr = key;
390         kbuf.dsize = strlen(key)+1;
391         
392         dbuf = tdb_fetch(tdb, kbuf);
393         if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
394
395         len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff", 
396                           &driver.cversion,
397                           driver.name,
398                           driver.environment,
399                           driver.driverpath,
400                           driver.datafile,
401                           driver.configfile,
402                           driver.helpfile,
403                           driver.monitorname,
404                           driver.defaultdatatype);
405
406         i=0;
407         while (len < dbuf.dsize) {
408                 driver.dependentfiles = (fstring *)Realloc(driver.dependentfiles,
409                                                          sizeof(fstring)*(i+2));
410                 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f", 
411                                   driver.dependentfiles[i]);
412                 i++;
413         }
414         fstrcpy(driver.dependentfiles[i], "");
415
416         free(dbuf.dptr);
417
418         if (len != dbuf.dsize) {
419                 return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
420         }
421
422         *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
423
424         return 0;
425 }
426
427 /****************************************************************************
428 debugging function, dump at level 6 the struct in the logs
429 ****************************************************************************/
430 static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
431 {
432         uint32 success;
433         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
434         int i;
435         
436         DEBUG(106,("Dumping printer driver at level [%d]\n", level));
437         
438         switch (level)
439         {
440                 case 3: 
441                 {
442                         if (driver.info_3 == NULL)
443                                 success=5;
444                         else {
445                                 info3=driver.info_3;
446                         
447                                 DEBUGADD(106,("version:[%d]\n",         info3->cversion));
448                                 DEBUGADD(106,("name:[%s]\n",            info3->name));
449                                 DEBUGADD(106,("environment:[%s]\n",     info3->environment));
450                                 DEBUGADD(106,("driverpath:[%s]\n",      info3->driverpath));
451                                 DEBUGADD(106,("datafile:[%s]\n",        info3->datafile));
452                                 DEBUGADD(106,("configfile:[%s]\n",      info3->configfile));
453                                 DEBUGADD(106,("helpfile:[%s]\n",        info3->helpfile));
454                                 DEBUGADD(106,("monitorname:[%s]\n",     info3->monitorname));
455                                 DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
456                                 
457                                 for (i=0; info3->dependentfiles &&
458                                           *info3->dependentfiles[i]; i++) {
459                                         DEBUGADD(106,("dependentfile:[%s]\n", 
460                                                       info3->dependentfiles[i]));
461                                 }
462                                 success=0;
463                         }
464                         break;
465                 }
466                 default:
467                         DEBUGADD(1,("Level not implemented\n"));
468                         success=1;
469                         break;
470         }
471         
472         return (success);
473 }
474
475 /****************************************************************************
476 ****************************************************************************/
477 static int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
478 {
479         int len = 0;
480
481         len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
482
483         if (!nt_devmode) return len;
484
485         len += tdb_pack(buf+len, buflen-len, "fddddddddddddddddddddddp",
486                        nt_devmode->formname,
487                        nt_devmode->specversion,
488                        nt_devmode->driverversion,
489                        nt_devmode->size,
490                        nt_devmode->driverextra,
491                        nt_devmode->fields,
492                        nt_devmode->orientation,
493                        nt_devmode->papersize,
494                        nt_devmode->paperlength,
495                        nt_devmode->paperwidth,
496                        nt_devmode->scale,
497                        nt_devmode->copies,
498                        nt_devmode->defaultsource,
499                        nt_devmode->printquality,
500                        nt_devmode->color,
501                        nt_devmode->duplex,
502                        nt_devmode->yresolution,
503                        nt_devmode->ttoption,
504                        nt_devmode->collate,
505                        nt_devmode->icmmethod,
506                        nt_devmode->icmintent,
507                        nt_devmode->mediatype,
508                        nt_devmode->dithertype,
509                        nt_devmode->private);
510         
511         if (nt_devmode->private) {
512                 len += tdb_pack(buf+len, buflen-len, "B",
513                                 nt_devmode->driverextra,
514                                 nt_devmode->private);
515         }
516
517         return len;
518 }
519
520 /****************************************************************************
521 ****************************************************************************/
522 static int pack_specifics(NT_PRINTER_PARAM *param, char *buf, int buflen)
523 {
524         int len = 0;
525
526         while (param != NULL) {
527                 len += tdb_pack(buf+len, buflen-len, "pfdB",
528                                 param,
529                                 param->value, 
530                                 param->type, 
531                                 param->data_len,
532                                 param->data);
533                 param=param->next;      
534         }
535
536         len += tdb_pack(buf+len, buflen-len, "p", param);
537
538         return len;
539 }
540
541
542 /****************************************************************************
543 delete a printer - this just deletes the printer info file, any open
544 handles are not affected
545 ****************************************************************************/
546 uint32 del_a_printer(char *portname)
547 {
548         pstring key;
549         TDB_DATA kbuf;
550
551         slprintf(key, sizeof(key), "%s/%s",
552                  PRINTERS_PREFIX, portname);
553
554         kbuf.dptr=key;
555         kbuf.dsize=strlen(key)+1;
556
557         tdb_delete(tdb, kbuf);
558         return 0;
559 }
560
561 /****************************************************************************
562 ****************************************************************************/
563 static uint32 add_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
564 {
565         pstring key;
566         char *buf;
567         int buflen, len, ret;
568         TDB_DATA kbuf, dbuf;
569         
570         /* 
571          * in addprinter: no servername and the printer is the name
572          * in setprinter: servername is \\server
573          *                and printer is \\server\\printer
574          *
575          * Samba manages only local printers.
576          * we currently don't support things like path=\\other_server\printer
577          */
578         if (info->servername[0]!='\0')
579         {
580                 trim_string(info->printername, info->servername, NULL);
581                 trim_string(info->printername, "\\", NULL);
582                 info->servername[0]='\0';
583         }
584
585         /*
586          * JFM: one day I'll forget.
587          * below that's info->portname because that's the SAMBA sharename
588          * and I made NT 'thinks' it's the portname
589          * the info->sharename is the thing you can name when you add a printer
590          * that's the short-name when you create shared printer for 95/98
591          * So I've made a limitation in SAMBA: you can only have 1 printer model
592          * behind a SAMBA share.
593          */
594
595
596         buf = NULL;
597         buflen = 0;
598
599  again: 
600         len = 0;
601         len += tdb_pack(buf+len, buflen-len, "dddddddddddffffffffff",
602                         info->attributes,
603                         info->priority,
604                         info->default_priority,
605                         info->starttime,
606                         info->untiltime,
607                         info->status,
608                         info->cjobs,
609                         info->averageppm,
610                         info->changeid,
611                         info->c_setprinter,
612                         info->setuptime,
613                         info->servername,
614                         info->printername,
615                         info->sharename,
616                         info->portname,
617                         info->drivername,
618                         info->location,
619                         info->sepfile,
620                         info->printprocessor,
621                         info->datatype,
622                         info->parameters);
623
624         len += pack_devicemode(info->devmode, buf+len, buflen-len);
625         len += pack_specifics(info->specific, buf+len, buflen-len);
626
627         if (buflen != len) {
628                 buf = (char *)Realloc(buf, len);
629                 buflen = len;
630                 goto again;
631         }
632         
633
634         slprintf(key, sizeof(key), "%s/%s",
635                  PRINTERS_PREFIX, info->portname);
636
637         kbuf.dptr = key;
638         kbuf.dsize = strlen(key)+1;
639         dbuf.dptr = buf;
640         dbuf.dsize = len;
641
642         ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
643
644         free(buf);
645
646         return ret;
647 }
648
649
650 /****************************************************************************
651 ****************************************************************************/
652 BOOL add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
653 {
654         NT_PRINTER_PARAM *current;
655         
656         DEBUG(108,("add_a_specific_param\n"));  
657
658         param->next=NULL;
659         
660         if (info_2->specific == NULL)
661         {
662                 info_2->specific=param;
663         }
664         else
665         {
666                 current=info_2->specific;               
667                 while (current->next != NULL) {
668                         current=current->next;
669                 }               
670                 current->next=param;
671         }
672         return (True);
673 }
674
675 /****************************************************************************
676 ****************************************************************************/
677 BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
678 {
679         NT_PRINTER_PARAM *current;
680         NT_PRINTER_PARAM *previous;
681         
682         current=info_2->specific;
683         previous=current;
684         
685         if (current==NULL) return (False);
686         
687         if ( !strcmp(current->value, param->value) && 
688             (strlen(current->value)==strlen(param->value)) )
689         {
690                 DEBUG(109,("deleting first value\n"));
691                 info_2->specific=current->next;
692                 safe_free(current->data);
693                 free(current);
694                 DEBUG(109,("deleted first value\n"));
695                 return (True);
696         }
697
698         current=previous->next;
699                 
700         while ( current!=NULL )
701         {
702                 if (!strcmp(current->value, param->value) &&
703                     strlen(current->value)==strlen(param->value) )
704                 {
705                         DEBUG(109,("deleting current value\n"));
706                         previous->next=current->next;
707                         free(current);
708                         DEBUG(109,("deleted current value\n"));
709                         return(True);
710                 }
711                 
712                 previous=previous->next;
713                 current=current->next;
714         }
715         return (False);
716 }
717
718 /****************************************************************************
719  Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
720 ****************************************************************************/
721 static void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr)
722 {
723         NT_PRINTER_PARAM *param = *param_ptr;
724
725         if(param == NULL)
726                 return;
727
728         DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param->value));
729
730         if(param->data)
731                 free(param->data);
732
733         free(param);
734         *param_ptr = NULL;
735 }
736
737 /****************************************************************************
738  Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
739 ****************************************************************************/
740 static void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
741 {
742         NT_DEVICEMODE *nt_devmode = *devmode_ptr;
743
744         if(nt_devmode == NULL)
745                 return;
746
747         DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
748
749         if(nt_devmode->private)
750                 free(nt_devmode->private);
751
752         free(nt_devmode);
753         *devmode_ptr = NULL;
754 }
755
756 /****************************************************************************
757  Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
758 ****************************************************************************/
759 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
760 {
761         NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
762         NT_PRINTER_PARAM *param_ptr;
763
764         if(info == NULL)
765                 return;
766
767         DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
768
769         free_nt_devicemode(&info->devmode);
770         free_sec_desc_buf(&info->secdesc);
771
772         for(param_ptr = info->specific; param_ptr; ) {
773                 NT_PRINTER_PARAM *tofree = param_ptr;
774
775                 param_ptr = param_ptr->next;
776                 free_nt_printer_param(&tofree);
777         }
778
779         *info_ptr = NULL;
780 }
781
782
783 /****************************************************************************
784 ****************************************************************************/
785 static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
786 {
787         int len = 0;
788         NT_DEVICEMODE devmode;
789
790         ZERO_STRUCT(devmode);
791
792         len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
793
794         if (!*nt_devmode) return len;
795
796         len += tdb_unpack(buf+len, buflen-len, "fddddddddddddddddddddddp",
797                        devmode.formname,
798                        &devmode.specversion,
799                        &devmode.driverversion,
800                        &devmode.size,
801                        &devmode.driverextra,
802                        &devmode.fields,
803                        &devmode.orientation,
804                        &devmode.papersize,
805                        &devmode.paperlength,
806                        &devmode.paperwidth,
807                        &devmode.scale,
808                        &devmode.copies,
809                        &devmode.defaultsource,
810                        &devmode.printquality,
811                        &devmode.color,
812                        &devmode.duplex,
813                        &devmode.yresolution,
814                        &devmode.ttoption,
815                        &devmode.collate,
816                        &devmode.icmmethod,
817                        &devmode.icmintent,
818                        &devmode.mediatype,
819                        &devmode.dithertype,
820                        &devmode.private);
821         
822         if (devmode.private) {
823                 devmode.private = (uint8 *)malloc(devmode.driverextra);
824                 if (!devmode.private) return 2;
825                 len += tdb_unpack(buf+len, buflen-len, "B",
826                                   devmode.driverextra,
827                                   devmode.private);
828         }
829
830         *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
831
832         return len;
833 }
834
835 /****************************************************************************
836 ****************************************************************************/
837 static int unpack_specifics(NT_PRINTER_PARAM **list, char *buf, int buflen)
838 {
839         int len = 0;
840         NT_PRINTER_PARAM param, *p;
841
842         *list = NULL;
843
844         while (1) {
845                 len += tdb_unpack(buf+len, buflen-len, "p", &p);
846                 if (!p) break;
847
848                 len += tdb_unpack(buf+len, buflen-len, "fdB",
849                                   param.value, 
850                                   &param.type, 
851                                   &param.data_len,
852                                   &param.data);
853                 param.next = *list;
854                 *list = memdup(&param, sizeof(param));
855         }
856
857         return len;
858 }
859
860
861 /****************************************************************************
862 get a default printer info 2 struct
863 ****************************************************************************/
864 static uint32 get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
865 {
866         extern pstring global_myname;
867         int snum;
868         NT_PRINTER_INFO_LEVEL_2 info;
869         NT_DEVICEMODE devmode;
870
871         ZERO_STRUCT(info);
872         ZERO_STRUCT(devmode);
873
874         init_devicemode(&devmode);
875         
876         snum = lp_servicenumber(sharename);
877
878         fstrcpy(info.servername, global_myname);
879         fstrcpy(info.printername, sharename);
880         fstrcpy(info.portname, sharename);
881         fstrcpy(info.drivername, lp_printerdriver(snum));
882         fstrcpy(info.printprocessor, "winprint");
883         fstrcpy(info.datatype, "RAW");
884
885         info.devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
886
887         nt_printing_getsec(sharename, &info.secdesc);
888
889         *info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
890         if (! *info_ptr) return 2;
891
892         return (0);     
893 }
894
895 /****************************************************************************
896 ****************************************************************************/
897 static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
898 {
899         pstring key;
900         NT_PRINTER_INFO_LEVEL_2 info;
901         int len = 0;
902         TDB_DATA kbuf, dbuf;
903                 
904         ZERO_STRUCT(info);
905
906         slprintf(key, sizeof(key), "%s/%s",
907                  PRINTERS_PREFIX, sharename);
908
909         kbuf.dptr = key;
910         kbuf.dsize = strlen(key)+1;
911
912         dbuf = tdb_fetch(tdb, kbuf);
913         if (!dbuf.dptr) return get_a_printer_2_default(info_ptr, sharename);
914
915         len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddffffffffff",
916                         &info.attributes,
917                         &info.priority,
918                         &info.default_priority,
919                         &info.starttime,
920                         &info.untiltime,
921                         &info.status,
922                         &info.cjobs,
923                         &info.averageppm,
924                         &info.changeid,
925                         &info.c_setprinter,
926                         &info.setuptime,
927                         info.servername,
928                         info.printername,
929                         info.sharename,
930                         info.portname,
931                         info.drivername,
932                         info.location,
933                         info.sepfile,
934                         info.printprocessor,
935                         info.datatype,
936                         info.parameters);
937
938         len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
939         len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
940
941         nt_printing_getsec(sharename, &info.secdesc);
942
943         *info_ptr=memdup(&info, sizeof(info));
944         
945         return 0;       
946 }
947
948 /****************************************************************************
949 debugging function, dump at level 6 the struct in the logs
950 ****************************************************************************/
951 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
952 {
953         uint32 success;
954         NT_PRINTER_INFO_LEVEL_2 *info2;
955         
956         DEBUG(106,("Dumping printer at level [%d]\n", level));
957         
958         switch (level)
959         {
960                 case 2: 
961                 {
962                         if (printer.info_2 == NULL)
963                                 success=5;
964                         else
965                         {
966                                 info2=printer.info_2;
967                         
968                                 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
969                                 DEBUGADD(106,("priority:[%d]\n", info2->priority));
970                                 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
971                                 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
972                                 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
973                                 DEBUGADD(106,("status:[%d]\n", info2->status));
974                                 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
975                                 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
976                                 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
977                                 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
978                                 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
979
980                                 DEBUGADD(106,("servername:[%s]\n", info2->servername));
981                                 DEBUGADD(106,("printername:[%s]\n", info2->printername));
982                                 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
983                                 DEBUGADD(106,("portname:[%s]\n", info2->portname));
984                                 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
985                                 DEBUGADD(106,("location:[%s]\n", info2->location));
986                                 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
987                                 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
988                                 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
989                                 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
990                                 success=0;
991                         }
992                         break;
993                 }
994                 default:
995                         DEBUGADD(1,("Level not implemented\n"));
996                         success=1;
997                         break;
998         }
999         
1000         return (success);
1001 }
1002
1003 /*
1004  * The function below are the high level ones.
1005  * only those ones must be called from the spoolss code.
1006  * JFM.
1007  */
1008
1009
1010 /****************************************************************************
1011 ****************************************************************************/
1012 uint32 add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1013 {
1014         uint32 success;
1015         
1016         dump_a_printer(printer, level); 
1017         
1018         switch (level)
1019         {
1020                 case 2: 
1021                 {
1022                         success=add_a_printer_2(printer.info_2);
1023                         break;
1024                 }
1025                 default:
1026                         success=1;
1027                         break;
1028         }
1029         
1030         return (success);
1031 }
1032
1033 /****************************************************************************
1034 ****************************************************************************/
1035 uint32 get_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level, fstring sharename)
1036 {
1037         uint32 success;
1038         
1039         DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
1040
1041         switch (level)
1042         {
1043                 case 2: 
1044                 {
1045                         printer->info_2=NULL;
1046                         success=get_a_printer_2(&(printer->info_2), sharename);
1047                         break;
1048                 }
1049                 default:
1050                         success=1;
1051                         break;
1052         }
1053         
1054         dump_a_printer(*printer, level);
1055
1056         DEBUG(10,("get_a_printer: [%s] level %u returning %u\n", sharename, (unsigned int)level, (unsigned int)success));
1057
1058         return (success);
1059 }
1060
1061 /****************************************************************************
1062 ****************************************************************************/
1063 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1064 {
1065         uint32 success;
1066         DEBUG(104,("freeing a printer at level [%d]\n", level));
1067         
1068         switch (level)
1069         {
1070                 case 2: 
1071                 {
1072                         if (printer.info_2 != NULL)
1073                         {
1074                                 free_nt_printer_info_level_2(&printer.info_2);
1075                                 success=0;
1076                         }
1077                         else
1078                         {
1079                                 success=4;
1080                         }
1081                         break;
1082                 }
1083                 default:
1084                         success=1;
1085                         break;
1086         }
1087         return (success);
1088 }
1089
1090 /****************************************************************************
1091 ****************************************************************************/
1092 uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1093 {
1094         uint32 success;
1095         DEBUG(104,("adding a printer at level [%d]\n", level));
1096         dump_a_printer_driver(driver, level);
1097         
1098         switch (level)
1099         {
1100                 case 3: 
1101                 {
1102                         success=add_a_printer_driver_3(driver.info_3);
1103                         break;
1104                 }
1105
1106                 case 6: 
1107                 {
1108                         success=add_a_printer_driver_6(driver.info_6);
1109                         break;
1110                 }
1111                 default:
1112                         success=1;
1113                         break;
1114         }
1115         
1116         return (success);
1117 }
1118 /****************************************************************************
1119 ****************************************************************************/
1120 uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level, 
1121                             fstring printername, fstring architecture)
1122 {
1123         uint32 success;
1124         
1125         switch (level)
1126         {
1127                 case 3: 
1128                 {
1129                         success=get_a_printer_driver_3(&(driver->info_3), 
1130                                                        printername,
1131                                                        architecture);
1132                         break;
1133                 }
1134                 default:
1135                         success=1;
1136                         break;
1137         }
1138         
1139         if (success == 0) dump_a_printer_driver(*driver, level);
1140         return (success);
1141 }
1142
1143 /****************************************************************************
1144 ****************************************************************************/
1145 uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1146 {
1147         uint32 success;
1148         NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1149         
1150         switch (level)
1151         {
1152                 case 3: 
1153                 {
1154                         if (driver.info_3 != NULL)
1155                         {
1156                                 info3=driver.info_3;
1157                                 if (info3->dependentfiles)
1158                                         free(info3->dependentfiles);
1159                                 free(info3);
1160                                 ZERO_STRUCTP(info3);
1161                                 success=0;
1162                         }
1163                         else
1164                         {
1165                                 success=4;
1166                         }
1167                         break;
1168                 }
1169                 default:
1170                         success=1;
1171                         break;
1172         }
1173         return (success);
1174 }
1175
1176 /****************************************************************************
1177 ****************************************************************************/
1178 BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
1179                                  fstring value, uint8 **data, uint32 *type, uint32 *len)
1180 {
1181         /* right now that's enough ! */ 
1182         NT_PRINTER_PARAM *param;
1183         int i=0;
1184         
1185         param=printer.info_2->specific;
1186         
1187         while (param != NULL && i <= param_index)
1188         {
1189                 param=param->next;
1190                 i++;
1191         }
1192         
1193         if (param == NULL)
1194                 return False;
1195
1196         /* exited because it exist */
1197         *type=param->type;              
1198         StrnCpy(value, param->value, sizeof(fstring)-1);
1199         *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
1200         if(*data == NULL)
1201                 return False;
1202         memcpy(*data, param->data, param->data_len);
1203         *len=param->data_len;
1204         return True;
1205 }
1206
1207 /****************************************************************************
1208 ****************************************************************************/
1209 BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level, 
1210                         fstring value, uint8 **data, uint32 *type, uint32 *len)
1211 {
1212         /* right now that's enough ! */ 
1213         NT_PRINTER_PARAM *param;
1214         
1215         DEBUG(105, ("get_specific_param\n"));
1216         
1217         param=printer.info_2->specific;
1218                 
1219         while (param != NULL)
1220         {
1221                 if ( !strcmp(value, param->value) 
1222                     && strlen(value)==strlen(param->value))
1223                         break;
1224                         
1225                 param=param->next;
1226         }
1227         
1228         DEBUG(106, ("found one param\n"));
1229         if (param != NULL)
1230         {
1231                 /* exited because it exist */
1232                 *type=param->type;      
1233                 
1234                 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
1235                 if(*data == NULL)
1236                         return False;
1237                 memcpy(*data, param->data, param->data_len);
1238                 *len=param->data_len;
1239
1240                 DEBUG(106, ("exit of get_specific_param:true\n"));
1241                 return (True);
1242         }
1243         DEBUG(106, ("exit of get_specific_param:false\n"));
1244         return (False);
1245 }
1246
1247 /****************************************************************************
1248 ****************************************************************************/
1249 void init_devicemode(NT_DEVICEMODE *nt_devmode)
1250 {
1251 /*
1252  * should I init this ones ???
1253         nt_devmode->devicename
1254 */
1255         fstrcpy(nt_devmode->formname, "A4");
1256
1257         nt_devmode->specversion      = 0x0401;
1258         nt_devmode->driverversion    = 0x0400;
1259         nt_devmode->size             = 0x00DC;
1260         nt_devmode->driverextra      = 0x0000;
1261         nt_devmode->fields           = FORMNAME | TTOPTION | PRINTQUALITY | 
1262                                        DEFAULTSOURCE | COPIES | SCALE | 
1263                                        PAPERSIZE | ORIENTATION;
1264         nt_devmode->orientation      = 1;
1265         nt_devmode->papersize        = PAPER_A4;
1266         nt_devmode->paperlength      = 0;
1267         nt_devmode->paperwidth       = 0;
1268         nt_devmode->scale            = 0x64;
1269         nt_devmode->copies           = 01;
1270         nt_devmode->defaultsource    = BIN_FORMSOURCE;
1271         nt_devmode->printquality     = 0x0258;
1272         nt_devmode->color            = COLOR_MONOCHROME;
1273         nt_devmode->duplex           = DUP_SIMPLEX;
1274         nt_devmode->yresolution      = 0;
1275         nt_devmode->ttoption         = TT_SUBDEV;
1276         nt_devmode->collate          = COLLATE_FALSE;
1277         nt_devmode->icmmethod        = 0;
1278         nt_devmode->icmintent        = 0;
1279         nt_devmode->mediatype        = 0;
1280         nt_devmode->dithertype       = 0;
1281
1282         /* non utilisés par un driver d'imprimante */
1283         nt_devmode->logpixels        = 0;
1284         nt_devmode->bitsperpel       = 0;
1285         nt_devmode->pelswidth        = 0;
1286         nt_devmode->pelsheight       = 0;
1287         nt_devmode->displayflags     = 0;
1288         nt_devmode->displayfrequency = 0;
1289         nt_devmode->reserved1        = 0;
1290         nt_devmode->reserved2        = 0;
1291         nt_devmode->panningwidth     = 0;
1292         nt_devmode->panningheight    = 0;
1293         
1294         nt_devmode->private=NULL;
1295 }
1296
1297
1298
1299 /****************************************************************************
1300 store a security desc for a printer
1301 ****************************************************************************/
1302 uint32 nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
1303 {
1304         prs_struct ps;
1305         fstring key;
1306         uint32 status;
1307
1308         prs_init(&ps, 0, 4, MARSHALL);
1309         ps.is_dynamic = True;
1310
1311         if (!sec_io_desc_buf("nt_printing_setsec", secdesc_ctr, &ps, 1)) {
1312                 status = ERROR_INVALID_FUNCTION;
1313                 goto out;
1314         }
1315
1316
1317         slprintf(key, sizeof(key), "SECDESC/%s", printername);
1318
1319         if (tdb_prs_store(tdb, key, &ps)==0) {
1320                 status = 0;
1321         } else {
1322                 DEBUG(1,("Failed to store secdesc for %s\n", printername));
1323                 status = ERROR_INVALID_FUNCTION;
1324         }
1325
1326  out:
1327         prs_mem_free(&ps);
1328         return status;
1329 }
1330
1331 /****************************************************************************
1332 get a security desc for a printer
1333 ****************************************************************************/
1334 uint32 nt_printing_getsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
1335 {
1336         prs_struct ps;
1337         fstring key;
1338
1339         slprintf(key, sizeof(key), "SECDESC/%s", printername);
1340
1341         if (tdb_prs_fetch(tdb, key, &ps)!=0 ||
1342             !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
1343                 DEBUG(4,("using default secdesc for %s\n", printername));
1344                 secdesc_ctr->len = convertperms_unix_to_sd(NULL, False,
1345                                                            0007,
1346                                                            &secdesc_ctr->sec);
1347                 secdesc_ctr->max_len = secdesc_ctr->len;
1348                 return 0;
1349         }
1350
1351         prs_mem_free(&ps);
1352         return 0;
1353 }
1354
1355 /* error code:
1356         0: everything OK
1357         1: level not implemented
1358         2: file doesn't exist
1359         3: can't allocate memory
1360         4: can't free memory
1361         5: non existant struct
1362 */
1363
1364 /*
1365         A printer and a printer driver are 2 different things.
1366         NT manages them separatelly, Samba does the same.
1367         Why ? Simply because it's easier and it makes sense !
1368         
1369         Now explanation: You have 3 printers behind your samba server,
1370         2 of them are the same make and model (laser A and B). But laser B 
1371         has an 3000 sheet feeder and laser A doesn't such an option.
1372         Your third printer is an old dot-matrix model for the accounting :-).
1373         
1374         If the /usr/local/samba/lib directory (default dir), you will have
1375         5 files to describe all of this.
1376         
1377         3 files for the printers (1 by printer):
1378                 NTprinter_laser A
1379                 NTprinter_laser B
1380                 NTprinter_accounting
1381         2 files for the drivers (1 for the laser and 1 for the dot matrix)
1382                 NTdriver_printer model X
1383                 NTdriver_printer model Y
1384
1385 jfm: I should use this comment for the text file to explain 
1386         same thing for the forms BTW.
1387         Je devrais mettre mes commentaires en francais, ca serait mieux :-)
1388
1389 */
1390
1391