2 * Unix SMB/Netbios implementation.
4 * RPC Pipe client / server routines
5 * Copyright (C) Andrew Tridgell 1992-2000,
6 * Copyright (C) Jean François Micouleau 1998-2000.
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.
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.
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.
25 extern int DEBUGLEVEL;
27 static TDB_CONTEXT *tdb; /* used for driver files */
29 #define FORMS_PREFIX "FORMS/"
30 #define DRIVERS_PREFIX "DRIVERS/"
31 #define PRINTERS_PREFIX "PRINTERS/"
33 #define DATABASE_VERSION 1
35 /* we need to have a small set of default forms to support our
37 static nt_forms_struct default_forms[] = {
38 {"Letter", 0x20, 0x34b5b, 0x44367, 0x0, 0x0, 0x34b5b, 0x44367},
39 {"A4", 0xb0, 0x3354f, 0x4884e, 0x0, 0x0, 0x3354f, 0x4884e}
43 /****************************************************************************
44 open the NT printing tdb
45 ****************************************************************************/
46 BOOL nt_printing_init(void)
48 static pid_t local_pid;
50 if (tdb && local_pid == sys_getpid()) return True;
51 tdb = tdb_open(lock_path("ntdrivers.tdb"), 0, 0, O_RDWR|O_CREAT, 0600);
53 DEBUG(0,("Failed to open nt drivers database\n"));
57 local_pid = sys_getpid();
59 /* handle a Samba upgrade */
61 if (tdb_fetch_int(tdb, "INFO/version") != DATABASE_VERSION) {
62 tdb_traverse(tdb, (tdb_traverse_func)tdb_delete, NULL);
63 tdb_store_int(tdb, "INFO/version", DATABASE_VERSION);
71 /****************************************************************************
72 get a form struct list
73 ****************************************************************************/
74 int get_ntforms(nt_forms_struct **list)
76 TDB_DATA kbuf, newkey, dbuf;
81 for (kbuf = tdb_firstkey(tdb);
83 newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
84 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0) continue;
86 dbuf = tdb_fetch(tdb, kbuf);
87 if (!dbuf.dptr) continue;
89 fstrcpy(form.name, kbuf.dptr+strlen(FORMS_PREFIX));
90 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddddddd",
91 &form.flag, &form.width, &form.length, &form.left,
92 &form.top, &form.right, &form.bottom);
94 if (ret != dbuf.dsize) continue;
96 *list = Realloc(*list, sizeof(nt_forms_struct)*(n+1));
101 /* we should never return a null forms list or NT gets unhappy */
103 *list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));
104 n = sizeof(default_forms) / sizeof(default_forms[0]);
111 /****************************************************************************
112 write a form struct list
113 ****************************************************************************/
114 int write_ntforms(nt_forms_struct **list, int number)
121 for (i=0;i<number;i++) {
122 len = tdb_pack(buf, sizeof(buf), "ddddddd",
123 (*list)[i].flag, (*list)[i].width, (*list)[i].length,
124 (*list)[i].left, (*list)[i].top, (*list)[i].right,
126 if (len > sizeof(buf)) break;
127 slprintf(key, sizeof(key), "%s%s", FORMS_PREFIX, (*list)[i].name);
128 kbuf.dsize = strlen(key)+1;
132 if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) break;
138 /****************************************************************************
139 add a form struct at the end of the list
140 ****************************************************************************/
141 BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
148 * NT tries to add forms even when
149 * they are already in the base
150 * only update the values if already present
155 unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
156 for (n=0; n<*count && update==False; n++)
158 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
160 DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
167 if((*list=Realloc(*list, (n+1)*sizeof(nt_forms_struct))) == NULL)
169 unistr2_to_ascii((*list)[n].name, &(form->name), sizeof((*list)[n].name)-1);
173 (*list)[n].flag=form->flags;
174 (*list)[n].width=form->size_x;
175 (*list)[n].length=form->size_y;
176 (*list)[n].left=form->left;
177 (*list)[n].top=form->top;
178 (*list)[n].right=form->right;
179 (*list)[n].bottom=form->bottom;
184 /****************************************************************************
186 ****************************************************************************/
187 void update_a_form(nt_forms_struct **list, const FORM *form, int count)
191 unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
193 DEBUG(106, ("[%s]\n", form_name));
194 for (n=0; n<count; n++)
196 DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
197 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
201 if (n==count) return;
203 (*list)[n].flag=form->flags;
204 (*list)[n].width=form->size_x;
205 (*list)[n].length=form->size_y;
206 (*list)[n].left=form->left;
207 (*list)[n].top=form->top;
208 (*list)[n].right=form->right;
209 (*list)[n].bottom=form->bottom;
212 /****************************************************************************
213 get the nt drivers list
215 traverse the database and look-up the matching names
216 ****************************************************************************/
217 int get_ntdrivers(fstring **list, char *architecture)
222 TDB_DATA kbuf, newkey;
224 get_short_archi(short_archi, architecture);
225 slprintf(key, sizeof(key), "%s%s/", DRIVERS_PREFIX, short_archi);
227 for (kbuf = tdb_firstkey(tdb);
229 newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
230 if (strncmp(kbuf.dptr, key, strlen(key)) != 0) continue;
232 if((*list = Realloc(*list, sizeof(fstring)*(total+1))) == NULL)
235 fstrcpy((*list)[total], kbuf.dptr+strlen(key));
242 /****************************************************************************
243 function to do the mapping between the long architecture name and
245 ****************************************************************************/
246 void get_short_archi(char *short_archi, char *long_archi)
253 struct table archi_table[]=
255 {"Windows 4.0", "WIN40" },
256 {"Windows NT x86", "W32X86" },
257 {"Windows NT R4000", "W32mips" },
258 {"Windows NT Alpha_AXP", "W32alpha" },
259 {"Windows NT PowerPC", "W32ppc" },
265 DEBUG(107,("Getting architecture dependant directory\n"));
268 } while ( (archi_table[i].long_archi!=NULL ) && strncmp(long_archi, archi_table[i].long_archi, strlen(long_archi)) );
270 if (archi_table[i].long_archi==NULL)
272 DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
274 StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
276 DEBUGADD(108,("index: [%d]\n", i));
277 DEBUGADD(108,("long architecture: [%s]\n", long_archi));
278 DEBUGADD(108,("short architecture: [%s]\n", short_archi));
281 /****************************************************************************
282 ****************************************************************************/
283 static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
286 fstring architecture;
292 get_short_archi(architecture, driver->environment);
293 slprintf(key, sizeof(key), "%s%s/%s", DRIVERS_PREFIX, architecture, driver->name);
296 * cversion must be 2.
297 * when adding a printer ON the SERVER
298 * rpcAddPrinterDriver defines it to zero
310 len += tdb_pack(buf+len, buflen-len, "dffffffff",
319 driver->defaultdatatype);
321 if (driver->dependentfiles) {
322 for (i=0; *driver->dependentfiles[i]; i++) {
323 len += tdb_pack(buf+len, buflen-len, "f",
324 driver->dependentfiles[i]);
329 buf = (char *)Realloc(buf, len);
336 kbuf.dsize = strlen(key)+1;
340 ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
346 /****************************************************************************
347 ****************************************************************************/
348 static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
350 NT_PRINTER_DRIVER_INFO_LEVEL_3 info3;
352 info3.cversion = driver->version;
353 fstrcpy(info3.environment,driver->environment);
354 fstrcpy(info3.driverpath,driver->driverpath);
355 fstrcpy(info3.datafile,driver->datafile);
356 fstrcpy(info3.configfile,driver->configfile);
357 fstrcpy(info3.helpfile,driver->helpfile);
358 fstrcpy(info3.monitorname,driver->monitorname);
359 fstrcpy(info3.defaultdatatype,driver->defaultdatatype);
360 info3.dependentfiles = driver->dependentfiles;
362 return add_a_printer_driver_3(&info3);
366 /****************************************************************************
367 ****************************************************************************/
368 static uint32 get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
370 NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
375 snum = lp_servicenumber(in_prt);
377 fstrcpy(info.name, lp_printerdriver(snum));
378 fstrcpy(info.defaultdatatype, "RAW");
380 if ((info.dependentfiles=(fstring *)malloc(sizeof(fstring))) == NULL)
381 return ERROR_NOT_ENOUGH_MEMORY;
383 fstrcpy(info.dependentfiles[0], "");
385 *info_ptr = memdup(&info, sizeof(info));
390 /****************************************************************************
391 ****************************************************************************/
392 static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
394 NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
396 fstring architecture;
403 get_short_archi(architecture, in_arch);
404 slprintf(key, sizeof(key), "%s%s/%s", DRIVERS_PREFIX, architecture, in_prt);
407 kbuf.dsize = strlen(key)+1;
409 dbuf = tdb_fetch(tdb, kbuf);
410 if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
412 len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff",
421 driver.defaultdatatype);
424 while (len < dbuf.dsize) {
425 driver.dependentfiles = (fstring *)Realloc(driver.dependentfiles,
426 sizeof(fstring)*(i+2));
427 if (driver.dependentfiles == NULL)
430 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f",
431 &driver.dependentfiles[i]);
434 if (driver.dependentfiles != NULL)
435 fstrcpy(driver.dependentfiles[i], "");
437 safe_free(dbuf.dptr);
439 if (len != dbuf.dsize) {
440 if (driver.dependentfiles != NULL)
441 safe_free(driver.dependentfiles);
443 return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
446 *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
451 /****************************************************************************
452 debugging function, dump at level 6 the struct in the logs
453 ****************************************************************************/
454 static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
457 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
460 DEBUG(106,("Dumping printer driver at level [%d]\n", level));
466 if (driver.info_3 == NULL)
471 DEBUGADD(106,("version:[%d]\n", info3->cversion));
472 DEBUGADD(106,("name:[%s]\n", info3->name));
473 DEBUGADD(106,("environment:[%s]\n", info3->environment));
474 DEBUGADD(106,("driverpath:[%s]\n", info3->driverpath));
475 DEBUGADD(106,("datafile:[%s]\n", info3->datafile));
476 DEBUGADD(106,("configfile:[%s]\n", info3->configfile));
477 DEBUGADD(106,("helpfile:[%s]\n", info3->helpfile));
478 DEBUGADD(106,("monitorname:[%s]\n", info3->monitorname));
479 DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
481 for (i=0; info3->dependentfiles &&
482 *info3->dependentfiles[i]; i++) {
483 DEBUGADD(106,("dependentfile:[%s]\n",
484 info3->dependentfiles[i]));
491 DEBUGADD(1,("Level not implemented\n"));
499 /****************************************************************************
500 ****************************************************************************/
501 static int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
505 len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
507 if (!nt_devmode) return len;
509 len += tdb_pack(buf+len, buflen-len, "fwwwwwwwwwwwwwwwwwwddddddddddddddp",
510 nt_devmode->formname,
512 nt_devmode->specversion,
513 nt_devmode->driverversion,
515 nt_devmode->driverextra,
516 nt_devmode->orientation,
517 nt_devmode->papersize,
518 nt_devmode->paperlength,
519 nt_devmode->paperwidth,
522 nt_devmode->defaultsource,
523 nt_devmode->printquality,
526 nt_devmode->yresolution,
527 nt_devmode->ttoption,
529 nt_devmode->logpixels,
532 nt_devmode->bitsperpel,
533 nt_devmode->pelswidth,
534 nt_devmode->pelsheight,
535 nt_devmode->displayflags,
536 nt_devmode->displayfrequency,
537 nt_devmode->icmmethod,
538 nt_devmode->icmintent,
539 nt_devmode->mediatype,
540 nt_devmode->dithertype,
541 nt_devmode->reserved1,
542 nt_devmode->reserved2,
543 nt_devmode->panningwidth,
544 nt_devmode->panningheight,
545 nt_devmode->private);
548 if (nt_devmode->private) {
549 len += tdb_pack(buf+len, buflen-len, "B",
550 nt_devmode->driverextra,
551 nt_devmode->private);
554 DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname));
559 /****************************************************************************
560 ****************************************************************************/
561 static int pack_specifics(NT_PRINTER_PARAM *param, char *buf, int buflen)
565 while (param != NULL) {
566 len += tdb_pack(buf+len, buflen-len, "pfdB",
575 len += tdb_pack(buf+len, buflen-len, "p", param);
581 /****************************************************************************
582 delete a printer - this just deletes the printer info file, any open
583 handles are not affected
584 ****************************************************************************/
585 uint32 del_a_printer(char *portname)
590 slprintf(key, sizeof(key), "%s%s",
591 PRINTERS_PREFIX, portname);
594 kbuf.dsize=strlen(key)+1;
596 tdb_delete(tdb, kbuf);
600 /****************************************************************************
601 ****************************************************************************/
602 static uint32 add_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
606 int buflen, len, ret;
610 * in addprinter: no servername and the printer is the name
611 * in setprinter: servername is \\server
612 * and printer is \\server\\printer
614 * Samba manages only local printers.
615 * we currently don't support things like path=\\other_server\printer
617 if (info->servername[0]!='\0')
619 trim_string(info->printername, info->servername, NULL);
620 trim_string(info->printername, "\\", NULL);
621 info->servername[0]='\0';
625 * JFM: one day I'll forget.
626 * below that's info->portname because that's the SAMBA sharename
627 * and I made NT 'thinks' it's the portname
628 * the info->sharename is the thing you can name when you add a printer
629 * that's the short-name when you create shared printer for 95/98
630 * So I've made a limitation in SAMBA: you can only have 1 printer model
631 * behind a SAMBA share.
640 len += tdb_pack(buf+len, buflen-len, "dddddddddddffffffffff",
643 info->default_priority,
659 info->printprocessor,
663 len += pack_devicemode(info->devmode, buf+len, buflen-len);
664 len += pack_specifics(info->specific, buf+len, buflen-len);
667 buf = (char *)Realloc(buf, len);
673 slprintf(key, sizeof(key), "%s%s",
674 PRINTERS_PREFIX, info->portname);
677 kbuf.dsize = strlen(key)+1;
681 ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
685 DEBUG(8,("packed printer [%s] with printprocessor [%s] parameters=[%s] len=%d\n",
686 info->portname, info->printprocessor, info->parameters, len));
692 /****************************************************************************
693 ****************************************************************************/
694 BOOL add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
696 NT_PRINTER_PARAM *current;
698 DEBUG(108,("add_a_specific_param\n"));
702 if (info_2->specific == NULL)
704 info_2->specific=param;
708 current=info_2->specific;
709 while (current->next != NULL) {
710 current=current->next;
717 /****************************************************************************
718 ****************************************************************************/
719 BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
721 NT_PRINTER_PARAM *current;
722 NT_PRINTER_PARAM *previous;
724 current=info_2->specific;
727 if (current==NULL) return (False);
729 if ( !strcmp(current->value, param->value) &&
730 (strlen(current->value)==strlen(param->value)) )
732 DEBUG(109,("deleting first value\n"));
733 info_2->specific=current->next;
734 safe_free(current->data);
736 DEBUG(109,("deleted first value\n"));
740 current=previous->next;
742 while ( current!=NULL )
744 if (!strcmp(current->value, param->value) &&
745 strlen(current->value)==strlen(param->value) )
747 DEBUG(109,("deleting current value\n"));
748 previous->next=current->next;
750 DEBUG(109,("deleted current value\n"));
754 previous=previous->next;
755 current=current->next;
760 /****************************************************************************
761 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
762 ****************************************************************************/
763 static void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr)
765 NT_PRINTER_PARAM *param = *param_ptr;
770 DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param->value));
773 safe_free(param->data);
779 /****************************************************************************
780 Malloc and return an NT devicemode.
781 ****************************************************************************/
783 NT_DEVICEMODE *construct_nt_devicemode(void)
786 * should I init this ones ???
787 nt_devmode->devicename
790 NT_DEVICEMODE *nt_devmode = (NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE));
792 if (nt_devmode == NULL) {
793 DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
797 ZERO_STRUCTP(nt_devmode);
799 fstrcpy(nt_devmode->formname, "Letter");
801 nt_devmode->specversion = 0x0401;
802 nt_devmode->driverversion = 0x0400;
803 nt_devmode->size = 0x00DC;
804 nt_devmode->driverextra = 0x0000;
805 nt_devmode->fields = FORMNAME | TTOPTION | PRINTQUALITY |
806 DEFAULTSOURCE | COPIES | SCALE |
807 PAPERSIZE | ORIENTATION;
808 nt_devmode->orientation = 1;
809 nt_devmode->papersize = PAPER_LETTER;
810 nt_devmode->paperlength = 0;
811 nt_devmode->paperwidth = 0;
812 nt_devmode->scale = 0x64;
813 nt_devmode->copies = 01;
814 nt_devmode->defaultsource = BIN_FORMSOURCE;
815 nt_devmode->printquality = 0x0258;
816 nt_devmode->color = COLOR_MONOCHROME;
817 nt_devmode->duplex = DUP_SIMPLEX;
818 nt_devmode->yresolution = 0;
819 nt_devmode->ttoption = TT_SUBDEV;
820 nt_devmode->collate = COLLATE_FALSE;
821 nt_devmode->icmmethod = 0;
822 nt_devmode->icmintent = 0;
823 nt_devmode->mediatype = 0;
824 nt_devmode->dithertype = 0;
826 /* non utilisés par un driver d'imprimante */
827 nt_devmode->logpixels = 0;
828 nt_devmode->bitsperpel = 0;
829 nt_devmode->pelswidth = 0;
830 nt_devmode->pelsheight = 0;
831 nt_devmode->displayflags = 0;
832 nt_devmode->displayfrequency = 0;
833 nt_devmode->reserved1 = 0;
834 nt_devmode->reserved2 = 0;
835 nt_devmode->panningwidth = 0;
836 nt_devmode->panningheight = 0;
838 nt_devmode->private=NULL;
843 /****************************************************************************
844 Deepcopy an NT devicemode.
845 ****************************************************************************/
847 NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
849 NT_DEVICEMODE *new_nt_devicemode = NULL;
851 if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
852 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
856 new_nt_devicemode->private = NULL;
857 if (nt_devicemode->private != NULL) {
858 if ((new_nt_devicemode->private = memdup(nt_devicemode->private, nt_devicemode->driverextra)) == NULL) {
859 safe_free(new_nt_devicemode);
860 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
865 return new_nt_devicemode;
868 /****************************************************************************
869 Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
870 ****************************************************************************/
872 void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
874 NT_DEVICEMODE *nt_devmode = *devmode_ptr;
876 if(nt_devmode == NULL)
879 DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
881 if(nt_devmode->private)
882 safe_free(nt_devmode->private);
884 safe_free(nt_devmode);
888 /****************************************************************************
889 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
890 ****************************************************************************/
891 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
893 NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
894 NT_PRINTER_PARAM *param_ptr;
899 DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
901 free_nt_devicemode(&info->devmode);
902 free_sec_desc_buf(&info->secdesc_buf);
904 for(param_ptr = info->specific; param_ptr; ) {
905 NT_PRINTER_PARAM *tofree = param_ptr;
907 param_ptr = param_ptr->next;
908 free_nt_printer_param(&tofree);
911 safe_free(*info_ptr);
916 /****************************************************************************
917 ****************************************************************************/
918 static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
921 NT_DEVICEMODE devmode;
923 ZERO_STRUCT(devmode);
925 len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
927 if (!*nt_devmode) return len;
929 len += tdb_unpack(buf+len, buflen-len, "fwwwwwwwwwwwwwwwwwwddddddddddddddp",
932 &devmode.specversion,
933 &devmode.driverversion,
935 &devmode.driverextra,
936 &devmode.orientation,
938 &devmode.paperlength,
942 &devmode.defaultsource,
943 &devmode.printquality,
946 &devmode.yresolution,
955 &devmode.displayflags,
956 &devmode.displayfrequency,
963 &devmode.panningwidth,
964 &devmode.panningheight,
967 if (devmode.private) {
968 devmode.private = (uint8 *)malloc(devmode.driverextra);
969 if (!devmode.private) return 2;
970 len += tdb_unpack(buf+len, buflen-len, "B",
975 *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
977 DEBUG(8,("Unpacked devicemode [%s]\n", devmode.formname));
982 /****************************************************************************
983 ****************************************************************************/
984 static int unpack_specifics(NT_PRINTER_PARAM **list, char *buf, int buflen)
987 NT_PRINTER_PARAM param, *p;
992 len += tdb_unpack(buf+len, buflen-len, "p", &p);
995 len += tdb_unpack(buf+len, buflen-len, "fdB",
1001 *list = memdup(¶m, sizeof(param));
1008 /****************************************************************************
1009 get a default printer info 2 struct
1010 ****************************************************************************/
1011 static uint32 get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
1013 extern pstring global_myname;
1015 NT_PRINTER_INFO_LEVEL_2 info;
1019 snum = lp_servicenumber(sharename);
1021 fstrcpy(info.servername, global_myname);
1022 fstrcpy(info.printername, sharename);
1023 fstrcpy(info.portname, sharename);
1024 fstrcpy(info.drivername, lp_printerdriver(snum));
1025 fstrcpy(info.printprocessor, "winprint");
1026 fstrcpy(info.datatype, "RAW");
1028 info.attributes = PRINTER_ATTRIBUTE_SHARED \
1029 | PRINTER_ATTRIBUTE_LOCAL \
1030 | PRINTER_ATTRIBUTE_RAW_ONLY ; /* attributes */
1032 info.starttime = 0; /* Minutes since 12:00am GMT */
1033 info.untiltime = 1440; /* Minutes since 12:00am GMT */
1035 if ((info.devmode = construct_nt_devicemode()) == NULL)
1038 if (!nt_printing_getsec(sharename, &info.secdesc_buf))
1041 *info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
1043 DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
1052 free_nt_devicemode(&info.devmode);
1053 if (info.secdesc_buf)
1054 free_sec_desc_buf(&info.secdesc_buf);
1058 /****************************************************************************
1059 ****************************************************************************/
1060 static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
1063 NT_PRINTER_INFO_LEVEL_2 info;
1065 TDB_DATA kbuf, dbuf;
1069 slprintf(key, sizeof(key), "%s%s",
1070 PRINTERS_PREFIX, sharename);
1073 kbuf.dsize = strlen(key)+1;
1075 dbuf = tdb_fetch(tdb, kbuf);
1076 if (!dbuf.dptr) return get_a_printer_2_default(info_ptr, sharename);
1078 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddffffffffff",
1081 &info.default_priority,
1097 info.printprocessor,
1101 info.attributes |= PRINTER_ATTRIBUTE_RAW_ONLY; /* Samba has to have raw drivers. */
1103 len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
1104 len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
1106 nt_printing_getsec(sharename, &info.secdesc_buf);
1108 fstrcpy(info.sharename, "");
1110 safe_free(dbuf.dptr);
1111 *info_ptr=memdup(&info, sizeof(info));
1113 DEBUG(9,("Unpacked printprocessor for [%s] of [%s]\n",
1114 sharename, info.printprocessor));
1120 /****************************************************************************
1121 debugging function, dump at level 6 the struct in the logs
1122 ****************************************************************************/
1123 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1126 NT_PRINTER_INFO_LEVEL_2 *info2;
1128 DEBUG(106,("Dumping printer at level [%d]\n", level));
1134 if (printer.info_2 == NULL)
1138 info2=printer.info_2;
1140 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
1141 DEBUGADD(106,("priority:[%d]\n", info2->priority));
1142 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
1143 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
1144 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
1145 DEBUGADD(106,("status:[%d]\n", info2->status));
1146 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
1147 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
1148 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
1149 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
1150 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
1152 DEBUGADD(106,("servername:[%s]\n", info2->servername));
1153 DEBUGADD(106,("printername:[%s]\n", info2->printername));
1154 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
1155 DEBUGADD(106,("portname:[%s]\n", info2->portname));
1156 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
1157 DEBUGADD(106,("location:[%s]\n", info2->location));
1158 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
1159 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
1160 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
1161 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
1167 DEBUGADD(1,("Level not implemented\n"));
1176 * The function below are the high level ones.
1177 * only those ones must be called from the spoolss code.
1182 /****************************************************************************
1183 ****************************************************************************/
1184 uint32 add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1188 dump_a_printer(printer, level);
1194 success=add_a_printer_2(printer.info_2);
1205 /****************************************************************************
1206 Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
1207 ****************************************************************************/
1209 uint32 get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename)
1212 NT_PRINTER_INFO_LEVEL *printer = NULL;
1216 DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
1222 if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
1223 DEBUG(0,("get_a_printer: malloc fail.\n"));
1226 ZERO_STRUCTP(printer);
1227 success=get_a_printer_2(&printer->info_2, sharename);
1229 dump_a_printer(*printer, level);
1230 *pp_printer = printer;
1241 DEBUG(10,("get_a_printer: [%s] level %u returning %u\n", sharename, (unsigned int)level, (unsigned int)success));
1246 /****************************************************************************
1247 Deletes a NT_PRINTER_INFO_LEVEL struct.
1248 ****************************************************************************/
1250 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
1253 NT_PRINTER_INFO_LEVEL *printer = *pp_printer;
1255 DEBUG(104,("freeing a printer at level [%d]\n", level));
1257 if (printer == NULL)
1264 if (printer->info_2 != NULL)
1266 free_nt_printer_info_level_2(&printer->info_2);
1285 /****************************************************************************
1286 ****************************************************************************/
1287 uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1290 DEBUG(104,("adding a printer at level [%d]\n", level));
1291 dump_a_printer_driver(driver, level);
1297 success=add_a_printer_driver_3(driver.info_3);
1303 success=add_a_printer_driver_6(driver.info_6);
1313 /****************************************************************************
1314 ****************************************************************************/
1315 uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
1316 fstring printername, fstring architecture)
1324 success=get_a_printer_driver_3(&(driver->info_3),
1334 if (success == 0) dump_a_printer_driver(*driver, level);
1338 /****************************************************************************
1339 ****************************************************************************/
1340 uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1348 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1349 if (driver.info_3 != NULL)
1351 info3=driver.info_3;
1352 safe_free(info3->dependentfiles);
1353 ZERO_STRUCTP(info3);
1365 NT_PRINTER_DRIVER_INFO_LEVEL_6 *info6;
1366 if (driver.info_6 != NULL)
1368 info6=driver.info_6;
1369 safe_free(info6->dependentfiles);
1370 ZERO_STRUCTP(info6);
1387 /****************************************************************************
1388 ****************************************************************************/
1389 BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
1390 fstring value, uint8 **data, uint32 *type, uint32 *len)
1392 /* right now that's enough ! */
1393 NT_PRINTER_PARAM *param;
1396 param=printer.info_2->specific;
1398 while (param != NULL && i <= param_index)
1407 /* exited because it exist */
1409 StrnCpy(value, param->value, sizeof(fstring)-1);
1410 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
1413 memcpy(*data, param->data, param->data_len);
1414 *len=param->data_len;
1418 /****************************************************************************
1419 ****************************************************************************/
1420 BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level,
1421 fstring value, uint8 **data, uint32 *type, uint32 *len)
1423 /* right now that's enough ! */
1424 NT_PRINTER_PARAM *param;
1426 DEBUG(105, ("get_specific_param\n"));
1428 param=printer.info_2->specific;
1430 while (param != NULL)
1432 if ( !strcmp(value, param->value)
1433 && strlen(value)==strlen(param->value))
1439 DEBUG(106, ("found one param\n"));
1442 /* exited because it exist */
1445 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
1448 memcpy(*data, param->data, param->data_len);
1449 *len=param->data_len;
1451 DEBUG(106, ("exit of get_specific_param:true\n"));
1454 DEBUG(106, ("exit of get_specific_param:false\n"));
1459 /****************************************************************************
1460 store a security desc for a printer
1461 ****************************************************************************/
1462 uint32 nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
1468 prs_init(&ps, (uint32)sec_desc_size(secdesc_ctr->sec) + sizeof(SEC_DESC_BUF), 4, MARSHALL);
1470 if (!sec_io_desc_buf("nt_printing_setsec", &secdesc_ctr, &ps, 1)) {
1471 status = ERROR_INVALID_FUNCTION;
1475 slprintf(key, sizeof(key), "SECDESC/%s", printername);
1477 if (tdb_prs_store(tdb, key, &ps)==0) {
1480 DEBUG(1,("Failed to store secdesc for %s\n", printername));
1481 status = ERROR_INVALID_FUNCTION;
1489 /****************************************************************************
1490 Construct a default security descriptor buffer for a printer.
1491 ****************************************************************************/
1493 static SEC_DESC_BUF *construct_default_printer_sdb(void)
1495 extern DOM_SID global_sid_World;
1498 SEC_ACL *psa = NULL;
1499 SEC_DESC_BUF *sdb = NULL;
1500 SEC_DESC *psd = NULL;
1503 init_sec_access(&sa,PRINTER_MANAGE_DOCUMENTS);
1504 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
1505 sa, SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
1506 init_sec_ace(&ace[1], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
1507 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
1509 if ((psa = make_sec_acl( ACL_REVISION, 2, &ace)) != NULL) {
1510 psd = make_sec_desc(SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT,
1511 &global_sid_World, &global_sid_World, NULL, psa, &sd_size);
1516 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
1520 sdb = make_sec_desc_buf(sd_size, psd);
1522 DEBUG(4,("construct_default_printer_sdb: size = %u.\n", (unsigned int)sd_size));
1524 free_sec_desc(&psd);
1528 /****************************************************************************
1529 Get a security desc for a printer.
1530 ****************************************************************************/
1532 BOOL nt_printing_getsec(char *printername, SEC_DESC_BUF **secdesc_ctr)
1537 slprintf(key, sizeof(key), "SECDESC/%s", printername);
1539 if (tdb_prs_fetch(tdb, key, &ps)!=0 ||
1540 !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
1542 DEBUG(4,("using default secdesc for %s\n", printername));
1544 if (!(*secdesc_ctr = construct_default_printer_sdb()))
1556 1: level not implemented
1557 2: file doesn't exist
1558 3: can't allocate memory
1559 4: can't free memory
1560 5: non existant struct
1564 A printer and a printer driver are 2 different things.
1565 NT manages them separatelly, Samba does the same.
1566 Why ? Simply because it's easier and it makes sense !
1568 Now explanation: You have 3 printers behind your samba server,
1569 2 of them are the same make and model (laser A and B). But laser B
1570 has an 3000 sheet feeder and laser A doesn't such an option.
1571 Your third printer is an old dot-matrix model for the accounting :-).
1573 If the /usr/local/samba/lib directory (default dir), you will have
1574 5 files to describe all of this.
1576 3 files for the printers (1 by printer):
1579 NTprinter_accounting
1580 2 files for the drivers (1 for the laser and 1 for the dot matrix)
1581 NTdriver_printer model X
1582 NTdriver_printer model Y
1584 jfm: I should use this comment for the text file to explain
1585 same thing for the forms BTW.
1586 Je devrais mettre mes commentaires en francais, ca serait mieux :-)