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;
26 extern pstring global_myname;
28 static TDB_CONTEXT *tdb; /* used for driver files */
30 #define FORMS_PREFIX "FORMS/"
31 #define DRIVERS_PREFIX "DRIVERS/"
32 #define PRINTERS_PREFIX "PRINTERS/"
34 #define DATABASE_VERSION 1
36 /* we need to have a small set of default forms to support our
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}
44 /****************************************************************************
45 open the NT printing tdb
46 ****************************************************************************/
47 BOOL nt_printing_init(void)
49 static pid_t local_pid;
51 if (tdb && local_pid == sys_getpid()) return True;
52 tdb = tdb_open(lock_path("ntdrivers.tdb"), 0, 0, O_RDWR|O_CREAT, 0600);
54 DEBUG(0,("Failed to open nt drivers database\n"));
58 local_pid = sys_getpid();
60 /* handle a Samba upgrade */
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);
72 /****************************************************************************
73 get a form struct list
74 ****************************************************************************/
75 int get_ntforms(nt_forms_struct **list)
77 TDB_DATA kbuf, newkey, dbuf;
82 for (kbuf = tdb_firstkey(tdb);
84 newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
85 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0) continue;
87 dbuf = tdb_fetch(tdb, kbuf);
88 if (!dbuf.dptr) continue;
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);
95 if (ret != dbuf.dsize) continue;
97 *list = Realloc(*list, sizeof(nt_forms_struct)*(n+1));
102 /* we should never return a null forms list or NT gets unhappy */
104 *list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));
105 n = sizeof(default_forms) / sizeof(default_forms[0]);
112 /****************************************************************************
113 write a form struct list
114 ****************************************************************************/
115 int write_ntforms(nt_forms_struct **list, int number)
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,
127 if (len > sizeof(buf)) break;
128 slprintf(key, sizeof(key), "%s%s", FORMS_PREFIX, (*list)[i].name);
129 kbuf.dsize = strlen(key)+1;
133 if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) break;
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)
149 * NT tries to add forms even when
150 * they are already in the base
151 * only update the values if already present
156 unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
157 for (n=0; n<*count && update==False; n++)
159 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
161 DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
168 if((*list=Realloc(*list, (n+1)*sizeof(nt_forms_struct))) == NULL)
170 unistr2_to_ascii((*list)[n].name, &(form->name), sizeof((*list)[n].name)-1);
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;
185 /****************************************************************************
187 ****************************************************************************/
188 void update_a_form(nt_forms_struct **list, const FORM *form, int count)
192 unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
194 DEBUG(106, ("[%s]\n", form_name));
195 for (n=0; n<count; n++)
197 DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
198 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
202 if (n==count) return;
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;
213 /****************************************************************************
214 get the nt drivers list
216 traverse the database and look-up the matching names
217 ****************************************************************************/
218 int get_ntdrivers(fstring **list, char *architecture)
223 TDB_DATA kbuf, newkey;
225 get_short_archi(short_archi, architecture);
226 slprintf(key, sizeof(key), "%s%s/", DRIVERS_PREFIX, short_archi);
228 for (kbuf = tdb_firstkey(tdb);
230 newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
231 if (strncmp(kbuf.dptr, key, strlen(key)) != 0) continue;
233 if((*list = Realloc(*list, sizeof(fstring)*(total+1))) == NULL)
236 fstrcpy((*list)[total], kbuf.dptr+strlen(key));
243 /****************************************************************************
244 function to do the mapping between the long architecture name and
246 ****************************************************************************/
247 void get_short_archi(char *short_archi, char *long_archi)
254 struct table archi_table[]=
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" },
266 DEBUG(107,("Getting architecture dependant directory\n"));
269 } while ( (archi_table[i].long_archi!=NULL ) && strncmp(long_archi, archi_table[i].long_archi, strlen(long_archi)) );
271 if (archi_table[i].long_archi==NULL)
273 DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
275 StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
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));
282 /****************************************************************************
283 ****************************************************************************/
284 static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
287 fstring architecture;
293 get_short_archi(architecture, driver->environment);
294 slprintf(key, sizeof(key), "%s%s/%s", DRIVERS_PREFIX, architecture, driver->name);
297 * cversion must be 2.
298 * when adding a printer ON the SERVER
299 * rpcAddPrinterDriver defines it to zero
311 len += tdb_pack(buf+len, buflen-len, "dffffffff",
320 driver->defaultdatatype);
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]);
330 buf = (char *)Realloc(buf, len);
337 kbuf.dsize = strlen(key)+1;
341 ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
347 /****************************************************************************
348 ****************************************************************************/
349 static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
351 NT_PRINTER_DRIVER_INFO_LEVEL_3 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;
364 return add_a_printer_driver_3(&info3);
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)
372 NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
377 snum = lp_servicenumber(in_prt);
379 fstrcpy(info.name, lp_printerdriver(snum));
380 fstrcpy(info.defaultdatatype, "RAW");
382 fstrcpy(info.driverpath, "");
383 fstrcpy(info.datafile, "");
384 fstrcpy(info.configfile, "");
385 fstrcpy(info.helpfile, "");
387 if ((info.dependentfiles=(fstring *)malloc(2*sizeof(fstring))) == NULL)
388 return ERROR_NOT_ENOUGH_MEMORY;
390 memset(info.dependentfiles, '\0', 2*sizeof(fstring));
391 fstrcpy(info.dependentfiles[0], "");
393 *info_ptr = memdup(&info, sizeof(info));
398 /****************************************************************************
399 ****************************************************************************/
400 static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
402 NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
404 fstring architecture;
411 get_short_archi(architecture, in_arch);
412 slprintf(key, sizeof(key), "%s%s/%s", DRIVERS_PREFIX, architecture, in_prt);
415 kbuf.dsize = strlen(key)+1;
417 dbuf = tdb_fetch(tdb, kbuf);
418 if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
420 len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff",
429 driver.defaultdatatype);
432 while (len < dbuf.dsize) {
433 driver.dependentfiles = (fstring *)Realloc(driver.dependentfiles,
434 sizeof(fstring)*(i+2));
435 if (driver.dependentfiles == NULL)
438 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f",
439 &driver.dependentfiles[i]);
442 if (driver.dependentfiles != NULL)
443 fstrcpy(driver.dependentfiles[i], "");
445 safe_free(dbuf.dptr);
447 if (len != dbuf.dsize) {
448 if (driver.dependentfiles != NULL)
449 safe_free(driver.dependentfiles);
451 return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
454 *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
459 /****************************************************************************
460 debugging function, dump at level 6 the struct in the logs
461 ****************************************************************************/
462 static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
465 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
468 DEBUG(106,("Dumping printer driver at level [%d]\n", level));
474 if (driver.info_3 == NULL)
479 DEBUGADD(106,("version:[%d]\n", info3->cversion));
480 DEBUGADD(106,("name:[%s]\n", info3->name));
481 DEBUGADD(106,("environment:[%s]\n", info3->environment));
482 DEBUGADD(106,("driverpath:[%s]\n", info3->driverpath));
483 DEBUGADD(106,("datafile:[%s]\n", info3->datafile));
484 DEBUGADD(106,("configfile:[%s]\n", info3->configfile));
485 DEBUGADD(106,("helpfile:[%s]\n", info3->helpfile));
486 DEBUGADD(106,("monitorname:[%s]\n", info3->monitorname));
487 DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
489 for (i=0; info3->dependentfiles &&
490 *info3->dependentfiles[i]; i++) {
491 DEBUGADD(106,("dependentfile:[%s]\n",
492 info3->dependentfiles[i]));
499 DEBUGADD(1,("Level not implemented\n"));
507 /****************************************************************************
508 ****************************************************************************/
509 static int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
513 len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
515 if (!nt_devmode) return len;
517 len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
518 nt_devmode->devicename,
519 nt_devmode->formname,
521 nt_devmode->specversion,
522 nt_devmode->driverversion,
524 nt_devmode->driverextra,
525 nt_devmode->orientation,
526 nt_devmode->papersize,
527 nt_devmode->paperlength,
528 nt_devmode->paperwidth,
531 nt_devmode->defaultsource,
532 nt_devmode->printquality,
535 nt_devmode->yresolution,
536 nt_devmode->ttoption,
538 nt_devmode->logpixels,
541 nt_devmode->bitsperpel,
542 nt_devmode->pelswidth,
543 nt_devmode->pelsheight,
544 nt_devmode->displayflags,
545 nt_devmode->displayfrequency,
546 nt_devmode->icmmethod,
547 nt_devmode->icmintent,
548 nt_devmode->mediatype,
549 nt_devmode->dithertype,
550 nt_devmode->reserved1,
551 nt_devmode->reserved2,
552 nt_devmode->panningwidth,
553 nt_devmode->panningheight,
554 nt_devmode->private);
557 if (nt_devmode->private) {
558 len += tdb_pack(buf+len, buflen-len, "B",
559 nt_devmode->driverextra,
560 nt_devmode->private);
563 DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname));
568 /****************************************************************************
569 ****************************************************************************/
570 static int pack_specifics(NT_PRINTER_PARAM *param, char *buf, int buflen)
574 while (param != NULL) {
575 len += tdb_pack(buf+len, buflen-len, "pfdB",
584 len += tdb_pack(buf+len, buflen-len, "p", param);
590 /****************************************************************************
591 delete a printer - this just deletes the printer info file, any open
592 handles are not affected
593 ****************************************************************************/
594 uint32 del_a_printer(char *portname)
599 slprintf(key, sizeof(key), "%s%s",
600 PRINTERS_PREFIX, portname);
603 kbuf.dsize=strlen(key)+1;
605 tdb_delete(tdb, kbuf);
609 /****************************************************************************
610 ****************************************************************************/
611 static uint32 add_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
615 int buflen, len, ret;
619 * in addprinter: no servername and the printer is the name
620 * in setprinter: servername is \\server
621 * and printer is \\server\\printer
623 * Samba manages only local printers.
624 * we currently don't support things like path=\\other_server\printer
626 if (info->servername[0]!='\0')
628 trim_string(info->printername, info->servername, NULL);
629 trim_string(info->printername, "\\", NULL);
630 info->servername[0]='\0';
634 * JFM: one day I'll forget.
635 * below that's info->portname because that's the SAMBA sharename
636 * and I made NT 'thinks' it's the portname
637 * the info->sharename is the thing you can name when you add a printer
638 * that's the short-name when you create shared printer for 95/98
639 * So I've made a limitation in SAMBA: you can only have 1 printer model
640 * behind a SAMBA share.
649 len += tdb_pack(buf+len, buflen-len, "dddddddddddffffffffff",
652 info->default_priority,
668 info->printprocessor,
672 len += pack_devicemode(info->devmode, buf+len, buflen-len);
673 len += pack_specifics(info->specific, buf+len, buflen-len);
676 buf = (char *)Realloc(buf, len);
682 slprintf(key, sizeof(key), "%s%s",
683 PRINTERS_PREFIX, info->portname);
686 kbuf.dsize = strlen(key)+1;
690 ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
694 DEBUG(8,("packed printer [%s] with printprocessor [%s] parameters=[%s] len=%d\n",
695 info->portname, info->printprocessor, info->parameters, len));
701 /****************************************************************************
702 ****************************************************************************/
703 BOOL add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
705 NT_PRINTER_PARAM *current;
707 DEBUG(108,("add_a_specific_param\n"));
711 if (info_2->specific == NULL)
713 info_2->specific=param;
717 current=info_2->specific;
718 while (current->next != NULL) {
719 current=current->next;
726 /****************************************************************************
727 ****************************************************************************/
728 BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
730 NT_PRINTER_PARAM *current;
731 NT_PRINTER_PARAM *previous;
733 current=info_2->specific;
736 if (current==NULL) return (False);
738 if ( !strcmp(current->value, param->value) &&
739 (strlen(current->value)==strlen(param->value)) ) {
740 DEBUG(109,("deleting first value\n"));
741 info_2->specific=current->next;
742 safe_free(current->data);
744 DEBUG(109,("deleted first value\n"));
748 current=previous->next;
750 while ( current!=NULL ) {
751 if (!strcmp(current->value, param->value) &&
752 strlen(current->value)==strlen(param->value) ) {
753 DEBUG(109,("deleting current value\n"));
754 previous->next=current->next;
755 safe_free(current->data);
757 DEBUG(109,("deleted current value\n"));
761 previous=previous->next;
762 current=current->next;
767 /****************************************************************************
768 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
769 ****************************************************************************/
770 static void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr)
772 NT_PRINTER_PARAM *param = *param_ptr;
777 DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param->value));
780 safe_free(param->data);
786 /****************************************************************************
787 Malloc and return an NT devicemode.
788 ****************************************************************************/
790 NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
793 * should I init this ones ???
794 nt_devmode->devicename
798 NT_DEVICEMODE *nt_devmode = (NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE));
800 if (nt_devmode == NULL) {
801 DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
805 ZERO_STRUCTP(nt_devmode);
807 snprintf(adevice, sizeof(adevice), "\\\\%s\\%s", global_myname, default_devicename);
808 fstrcpy(nt_devmode->devicename, adevice);
811 fstrcpy(nt_devmode->formname, "Letter");
813 nt_devmode->specversion = 0x0401;
814 nt_devmode->driverversion = 0x0400;
815 nt_devmode->size = 0x00DC;
816 nt_devmode->driverextra = 0x0000;
817 nt_devmode->fields = FORMNAME | TTOPTION | PRINTQUALITY |
818 DEFAULTSOURCE | COPIES | SCALE |
819 PAPERSIZE | ORIENTATION;
820 nt_devmode->orientation = 1;
821 nt_devmode->papersize = PAPER_LETTER;
822 nt_devmode->paperlength = 0;
823 nt_devmode->paperwidth = 0;
824 nt_devmode->scale = 0x64;
825 nt_devmode->copies = 01;
826 nt_devmode->defaultsource = BIN_FORMSOURCE;
827 nt_devmode->printquality = 0x0258;
828 nt_devmode->color = COLOR_MONOCHROME;
829 nt_devmode->duplex = DUP_SIMPLEX;
830 nt_devmode->yresolution = 0;
831 nt_devmode->ttoption = TT_SUBDEV;
832 nt_devmode->collate = COLLATE_FALSE;
833 nt_devmode->icmmethod = 0;
834 nt_devmode->icmintent = 0;
835 nt_devmode->mediatype = 0;
836 nt_devmode->dithertype = 0;
838 /* non utilisés par un driver d'imprimante */
839 nt_devmode->logpixels = 0;
840 nt_devmode->bitsperpel = 0;
841 nt_devmode->pelswidth = 0;
842 nt_devmode->pelsheight = 0;
843 nt_devmode->displayflags = 0;
844 nt_devmode->displayfrequency = 0;
845 nt_devmode->reserved1 = 0;
846 nt_devmode->reserved2 = 0;
847 nt_devmode->panningwidth = 0;
848 nt_devmode->panningheight = 0;
850 nt_devmode->private=NULL;
855 /****************************************************************************
856 Deepcopy an NT devicemode.
857 ****************************************************************************/
859 NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
861 NT_DEVICEMODE *new_nt_devicemode = NULL;
863 if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
864 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
868 new_nt_devicemode->private = NULL;
869 if (nt_devicemode->private != NULL) {
870 if ((new_nt_devicemode->private = memdup(nt_devicemode->private, nt_devicemode->driverextra)) == NULL) {
871 safe_free(new_nt_devicemode);
872 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
877 return new_nt_devicemode;
880 /****************************************************************************
881 Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
882 ****************************************************************************/
884 void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
886 NT_DEVICEMODE *nt_devmode = *devmode_ptr;
888 if(nt_devmode == NULL)
891 DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
893 if(nt_devmode->private)
894 safe_free(nt_devmode->private);
896 safe_free(nt_devmode);
900 /****************************************************************************
901 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
902 ****************************************************************************/
903 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
905 NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
906 NT_PRINTER_PARAM *param_ptr;
911 DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
913 free_nt_devicemode(&info->devmode);
914 free_sec_desc_buf(&info->secdesc_buf);
916 for(param_ptr = info->specific; param_ptr; ) {
917 NT_PRINTER_PARAM *tofree = param_ptr;
919 param_ptr = param_ptr->next;
920 free_nt_printer_param(&tofree);
923 safe_free(*info_ptr);
928 /****************************************************************************
929 ****************************************************************************/
930 static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
933 NT_DEVICEMODE devmode;
935 ZERO_STRUCT(devmode);
937 len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
939 if (!*nt_devmode) return len;
941 len += tdb_unpack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
945 &devmode.specversion,
946 &devmode.driverversion,
948 &devmode.driverextra,
949 &devmode.orientation,
951 &devmode.paperlength,
955 &devmode.defaultsource,
956 &devmode.printquality,
959 &devmode.yresolution,
968 &devmode.displayflags,
969 &devmode.displayfrequency,
976 &devmode.panningwidth,
977 &devmode.panningheight,
980 if (devmode.private) {
981 devmode.private = (uint8 *)malloc(devmode.driverextra);
982 if (!devmode.private) return 2;
983 len += tdb_unpack(buf+len, buflen-len, "B",
988 *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
990 DEBUG(8,("Unpacked devicemode [%s]\n", devmode.formname));
995 /****************************************************************************
996 ****************************************************************************/
997 static int unpack_specifics(NT_PRINTER_PARAM **list, char *buf, int buflen)
1000 NT_PRINTER_PARAM param, *p;
1005 len += tdb_unpack(buf+len, buflen-len, "p", &p);
1008 len += tdb_unpack(buf+len, buflen-len, "fdB",
1014 *list = memdup(¶m, sizeof(param));
1021 /****************************************************************************
1022 get a default printer info 2 struct
1023 ****************************************************************************/
1024 static uint32 get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
1026 extern pstring global_myname;
1028 NT_PRINTER_INFO_LEVEL_2 info;
1032 snum = lp_servicenumber(sharename);
1034 fstrcpy(info.servername, global_myname);
1035 fstrcpy(info.printername, sharename);
1036 fstrcpy(info.portname, sharename);
1037 fstrcpy(info.drivername, lp_printerdriver(snum));
1038 fstrcpy(info.printprocessor, "winprint");
1039 fstrcpy(info.datatype, "RAW");
1041 info.attributes = PRINTER_ATTRIBUTE_SHARED \
1042 | PRINTER_ATTRIBUTE_LOCAL \
1043 | PRINTER_ATTRIBUTE_RAW_ONLY ; /* attributes */
1045 info.starttime = 0; /* Minutes since 12:00am GMT */
1046 info.untiltime = 0; /* Minutes since 12:00am GMT */
1048 info.default_priority = 1;
1050 if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
1053 if (!nt_printing_getsec(sharename, &info.secdesc_buf))
1056 *info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
1058 DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
1067 free_nt_devicemode(&info.devmode);
1068 if (info.secdesc_buf)
1069 free_sec_desc_buf(&info.secdesc_buf);
1073 /****************************************************************************
1074 ****************************************************************************/
1075 static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
1078 NT_PRINTER_INFO_LEVEL_2 info;
1080 TDB_DATA kbuf, dbuf;
1084 slprintf(key, sizeof(key), "%s%s",
1085 PRINTERS_PREFIX, sharename);
1088 kbuf.dsize = strlen(key)+1;
1090 dbuf = tdb_fetch(tdb, kbuf);
1092 if (!dbuf.dptr) return get_a_printer_2_default(info_ptr, sharename);
1094 if (!dbuf.dptr) return 1;
1097 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddffffffffff",
1100 &info.default_priority,
1116 info.printprocessor,
1120 info.attributes |= PRINTER_ATTRIBUTE_RAW_ONLY; /* Samba has to have raw drivers. */
1122 len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
1123 len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
1126 nt_printing_getsec(sharename, &info.secdesc_buf);
1127 #endif /* JRATEST */
1129 fstrcpy(info.sharename, "");
1131 safe_free(dbuf.dptr);
1132 *info_ptr=memdup(&info, sizeof(info));
1134 DEBUG(9,("Unpacked printprocessor for [%s] of [%s]\n",
1135 sharename, info.printprocessor));
1141 /****************************************************************************
1142 debugging function, dump at level 6 the struct in the logs
1143 ****************************************************************************/
1144 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1147 NT_PRINTER_INFO_LEVEL_2 *info2;
1149 DEBUG(106,("Dumping printer at level [%d]\n", level));
1155 if (printer.info_2 == NULL)
1159 info2=printer.info_2;
1161 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
1162 DEBUGADD(106,("priority:[%d]\n", info2->priority));
1163 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
1164 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
1165 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
1166 DEBUGADD(106,("status:[%d]\n", info2->status));
1167 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
1168 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
1169 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
1170 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
1171 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
1173 DEBUGADD(106,("servername:[%s]\n", info2->servername));
1174 DEBUGADD(106,("printername:[%s]\n", info2->printername));
1175 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
1176 DEBUGADD(106,("portname:[%s]\n", info2->portname));
1177 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
1178 DEBUGADD(106,("location:[%s]\n", info2->location));
1179 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
1180 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
1181 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
1182 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
1188 DEBUGADD(1,("Level not implemented\n"));
1197 * The function below are the high level ones.
1198 * only those ones must be called from the spoolss code.
1203 /****************************************************************************
1204 ****************************************************************************/
1205 uint32 add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1209 dump_a_printer(printer, level);
1215 success=add_a_printer_2(printer.info_2);
1226 /****************************************************************************
1227 Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
1228 ****************************************************************************/
1230 uint32 get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename)
1233 NT_PRINTER_INFO_LEVEL *printer = NULL;
1237 DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
1243 if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
1244 DEBUG(0,("get_a_printer: malloc fail.\n"));
1247 ZERO_STRUCTP(printer);
1248 success=get_a_printer_2(&printer->info_2, sharename);
1250 dump_a_printer(*printer, level);
1251 *pp_printer = printer;
1262 DEBUG(10,("get_a_printer: [%s] level %u returning %u\n", sharename, (unsigned int)level, (unsigned int)success));
1267 /****************************************************************************
1268 Deletes a NT_PRINTER_INFO_LEVEL struct.
1269 ****************************************************************************/
1271 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
1274 NT_PRINTER_INFO_LEVEL *printer = *pp_printer;
1276 DEBUG(104,("freeing a printer at level [%d]\n", level));
1278 if (printer == NULL)
1285 if (printer->info_2 != NULL)
1287 free_nt_printer_info_level_2(&printer->info_2);
1306 /****************************************************************************
1307 ****************************************************************************/
1308 uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1311 DEBUG(104,("adding a printer at level [%d]\n", level));
1312 dump_a_printer_driver(driver, level);
1318 success=add_a_printer_driver_3(driver.info_3);
1324 success=add_a_printer_driver_6(driver.info_6);
1334 /****************************************************************************
1335 ****************************************************************************/
1336 uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
1337 fstring printername, fstring architecture)
1345 success=get_a_printer_driver_3(&(driver->info_3),
1355 if (success == 0) dump_a_printer_driver(*driver, level);
1359 /****************************************************************************
1360 ****************************************************************************/
1361 uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1369 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1370 if (driver.info_3 != NULL)
1372 info3=driver.info_3;
1373 safe_free(info3->dependentfiles);
1374 ZERO_STRUCTP(info3);
1386 NT_PRINTER_DRIVER_INFO_LEVEL_6 *info6;
1387 if (driver.info_6 != NULL)
1389 info6=driver.info_6;
1390 safe_free(info6->dependentfiles);
1391 safe_free(info6->previousnames);
1392 ZERO_STRUCTP(info6);
1409 /****************************************************************************
1410 ****************************************************************************/
1411 BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
1412 fstring value, uint8 **data, uint32 *type, uint32 *len)
1414 /* right now that's enough ! */
1415 NT_PRINTER_PARAM *param;
1418 param=printer.info_2->specific;
1420 while (param != NULL && i <= param_index)
1429 /* exited because it exist */
1431 StrnCpy(value, param->value, sizeof(fstring)-1);
1432 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
1435 memcpy(*data, param->data, param->data_len);
1436 *len=param->data_len;
1440 /****************************************************************************
1441 ****************************************************************************/
1442 BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level,
1443 fstring value, uint8 **data, uint32 *type, uint32 *len)
1445 /* right now that's enough ! */
1446 NT_PRINTER_PARAM *param;
1448 DEBUG(105, ("get_specific_param\n"));
1450 param=printer.info_2->specific;
1452 while (param != NULL)
1454 if ( !strcmp(value, param->value)
1455 && strlen(value)==strlen(param->value))
1461 DEBUG(106, ("found one param\n"));
1464 /* exited because it exist */
1467 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
1470 memcpy(*data, param->data, param->data_len);
1471 *len=param->data_len;
1473 DEBUG(106, ("exit of get_specific_param:true\n"));
1476 DEBUG(106, ("exit of get_specific_param:false\n"));
1481 /****************************************************************************
1482 store a security desc for a printer
1483 ****************************************************************************/
1484 uint32 nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
1486 SEC_DESC_BUF *new_secdesc_ctr = NULL;
1491 /* The old owner and group sids of the security descriptor are not
1492 present when new ACEs are added or removed by changing printer
1493 permissions through NT. If they are NULL in the new security
1494 descriptor then copy them over from the old one. */
1496 if (!secdesc_ctr->sec->owner_sid || !secdesc_ctr->sec->grp_sid) {
1497 SEC_DESC_BUF *old_secdesc_ctr = NULL;
1498 DOM_SID *owner_sid, *group_sid;
1499 SEC_DESC *psd = NULL;
1502 /* Get old security descriptor */
1504 if (!nt_printing_getsec(printername, &old_secdesc_ctr)) {
1505 DEBUG(0, ("could not get old security descriptor for "
1506 "printer %s", printername));
1507 return ERROR_INVALID_FUNCTION;
1510 /* Pick out correct owner and group sids */
1512 owner_sid = secdesc_ctr->sec->owner_sid ?
1513 secdesc_ctr->sec->owner_sid :
1514 old_secdesc_ctr->sec->owner_sid;
1516 group_sid = secdesc_ctr->sec->grp_sid ?
1517 secdesc_ctr->sec->grp_sid :
1518 old_secdesc_ctr->sec->grp_sid;
1520 /* Make a deep copy of the security descriptor */
1522 psd = make_sec_desc(secdesc_ctr->sec->revision,
1523 secdesc_ctr->sec->type,
1524 owner_sid, group_sid,
1525 secdesc_ctr->sec->sacl,
1526 secdesc_ctr->sec->dacl,
1529 new_secdesc_ctr = make_sec_desc_buf(size, psd);
1531 /* Free up memory */
1533 free_sec_desc(&psd);
1534 free_sec_desc_buf(&old_secdesc_ctr);
1537 if (!new_secdesc_ctr) {
1538 new_secdesc_ctr = secdesc_ctr;
1541 /* Store the security descriptor in a tdb */
1543 prs_init(&ps, (uint32)sec_desc_size(new_secdesc_ctr->sec) +
1544 sizeof(SEC_DESC_BUF), 4, MARSHALL);
1546 if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr,
1548 status = ERROR_INVALID_FUNCTION;
1552 slprintf(key, sizeof(key), "SECDESC/%s", printername);
1554 if (tdb_prs_store(tdb, key, &ps)==0) {
1557 DEBUG(1,("Failed to store secdesc for %s\n", printername));
1558 status = ERROR_INVALID_FUNCTION;
1562 if (new_secdesc_ctr != secdesc_ctr) {
1563 free_sec_desc_buf(&new_secdesc_ctr);
1570 /****************************************************************************
1571 Construct a default security descriptor buffer for a printer.
1572 ****************************************************************************/
1574 static SEC_DESC_BUF *construct_default_printer_sdb(void)
1576 extern DOM_SID global_sid_World;
1579 SEC_ACL *psa = NULL;
1580 SEC_DESC_BUF *sdb = NULL;
1581 SEC_DESC *psd = NULL;
1584 init_sec_access(&sa,PRINTER_ACE_FULL_CONTROL);
1585 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
1586 sa, SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
1587 init_sec_ace(&ace[1], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
1588 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
1590 if ((psa = make_sec_acl( ACL_REVISION, 2, ace)) != NULL) {
1591 psd = make_sec_desc(SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT,
1592 &global_sid_World, &global_sid_World, NULL, psa, &sd_size);
1597 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
1601 sdb = make_sec_desc_buf(sd_size, psd);
1603 DEBUG(4,("construct_default_printer_sdb: size = %u.\n", (unsigned int)sd_size));
1605 free_sec_desc(&psd);
1609 /****************************************************************************
1610 Get a security desc for a printer.
1611 ****************************************************************************/
1613 BOOL nt_printing_getsec(char *printername, SEC_DESC_BUF **secdesc_ctr)
1618 slprintf(key, sizeof(key), "SECDESC/%s", printername);
1620 if (tdb_prs_fetch(tdb, key, &ps)!=0 ||
1621 !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
1623 DEBUG(4,("using default secdesc for %s\n", printername));
1625 if (!(*secdesc_ctr = construct_default_printer_sdb()))
1637 1: level not implemented
1638 2: file doesn't exist
1639 3: can't allocate memory
1640 4: can't free memory
1641 5: non existant struct
1645 A printer and a printer driver are 2 different things.
1646 NT manages them separatelly, Samba does the same.
1647 Why ? Simply because it's easier and it makes sense !
1649 Now explanation: You have 3 printers behind your samba server,
1650 2 of them are the same make and model (laser A and B). But laser B
1651 has an 3000 sheet feeder and laser A doesn't such an option.
1652 Your third printer is an old dot-matrix model for the accounting :-).
1654 If the /usr/local/samba/lib directory (default dir), you will have
1655 5 files to describe all of this.
1657 3 files for the printers (1 by printer):
1660 NTprinter_accounting
1661 2 files for the drivers (1 for the laser and 1 for the dot matrix)
1662 NTdriver_printer model X
1663 NTdriver_printer model Y
1665 jfm: I should use this comment for the text file to explain
1666 same thing for the forms BTW.
1667 Je devrais mettre mes commentaires en francais, ca serait mieux :-)
1671 /* Check a user has permissions to perform the given operation */
1673 BOOL print_access_check(struct current_user *user, int snum,
1674 uint32 required_access)
1676 SEC_DESC_BUF *secdesc = NULL;
1677 uint32 access_granted, status;
1682 /* Get printer name */
1684 pname = PRINTERNAME(snum);
1685 if (!pname || !*pname) pname = SERVICE(snum);
1687 /* Get printer security descriptor */
1689 nt_printing_getsec(pname, &secdesc);
1691 /* The ACE for Full Control in a printer security descriptor
1692 doesn't seem to map properly to the access checking model. For
1693 it to work properly it should be the logical OR of all the other
1694 values, i.e PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT.
1695 This would cause the access check to simply fall out when we
1696 check against any subset of these bits. To get things to work,
1697 change every ACE mask of PRINTER_ACE_FULL_CONTROL to
1698 PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT before
1699 performing the access check. I'm sure there is a better way to
1702 if (secdesc && secdesc->sec && secdesc->sec->dacl &&
1703 secdesc->sec->dacl->ace) {
1704 for(i = 0; i < secdesc->sec->dacl->num_aces; i++) {
1705 if (secdesc->sec->dacl->ace[i].info.mask ==
1706 PRINTER_ACE_FULL_CONTROL) {
1707 secdesc->sec->dacl->ace[i].info.mask =
1708 PRINTER_ACE_MANAGE_DOCUMENTS |
1716 result = se_access_check(secdesc->sec, user->uid, user->gid,
1717 user->ngroups, user->groups,
1718 required_access, &access_granted, &status);
1720 DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE"));
1722 /* Free mallocated memory */
1724 free_sec_desc_buf(&secdesc);