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;
27 extern DOM_SID global_sid_World;
29 static TDB_CONTEXT *tdb; /* used for driver files */
31 #define FORMS_PREFIX "FORMS/"
32 #define DRIVERS_PREFIX "DRIVERS/"
33 #define PRINTERS_PREFIX "PRINTERS/"
35 #define DATABASE_VERSION 1
37 /* we need to have a small set of default forms to support our
39 static nt_forms_struct default_forms[] = {
40 {"Letter", 0x20, 0x34b5b, 0x44367, 0x0, 0x0, 0x34b5b, 0x44367},
41 {"A4", 0xb0, 0x3354f, 0x4884e, 0x0, 0x0, 0x3354f, 0x4884e}
45 /****************************************************************************
46 open the NT printing tdb
47 ****************************************************************************/
48 BOOL nt_printing_init(void)
50 static pid_t local_pid;
52 if (tdb && local_pid == sys_getpid()) return True;
53 tdb = tdb_open(lock_path("ntdrivers.tdb"), 0, 0, O_RDWR|O_CREAT, 0600);
55 DEBUG(0,("Failed to open nt drivers database\n"));
59 local_pid = sys_getpid();
61 /* handle a Samba upgrade */
63 if (tdb_fetch_int(tdb, "INFO/version") != DATABASE_VERSION) {
64 tdb_traverse(tdb, (tdb_traverse_func)tdb_delete, NULL);
65 tdb_store_int(tdb, "INFO/version", DATABASE_VERSION);
73 /****************************************************************************
74 get a form struct list
75 ****************************************************************************/
76 int get_ntforms(nt_forms_struct **list)
78 TDB_DATA kbuf, newkey, dbuf;
83 for (kbuf = tdb_firstkey(tdb);
85 newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
86 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0) continue;
88 dbuf = tdb_fetch(tdb, kbuf);
89 if (!dbuf.dptr) continue;
91 fstrcpy(form.name, kbuf.dptr+strlen(FORMS_PREFIX));
92 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddddddd",
93 &form.flag, &form.width, &form.length, &form.left,
94 &form.top, &form.right, &form.bottom);
96 if (ret != dbuf.dsize) continue;
98 *list = Realloc(*list, sizeof(nt_forms_struct)*(n+1));
103 /* we should never return a null forms list or NT gets unhappy */
105 *list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));
106 n = sizeof(default_forms) / sizeof(default_forms[0]);
113 /****************************************************************************
114 write a form struct list
115 ****************************************************************************/
116 int write_ntforms(nt_forms_struct **list, int number)
123 for (i=0;i<number;i++) {
124 len = tdb_pack(buf, sizeof(buf), "ddddddd",
125 (*list)[i].flag, (*list)[i].width, (*list)[i].length,
126 (*list)[i].left, (*list)[i].top, (*list)[i].right,
128 if (len > sizeof(buf)) break;
129 slprintf(key, sizeof(key), "%s%s", FORMS_PREFIX, (*list)[i].name);
130 kbuf.dsize = strlen(key)+1;
134 if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) break;
140 /****************************************************************************
141 add a form struct at the end of the list
142 ****************************************************************************/
143 BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
150 * NT tries to add forms even when
151 * they are already in the base
152 * only update the values if already present
157 unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
158 for (n=0; n<*count && update==False; n++)
160 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
162 DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
169 if((*list=Realloc(*list, (n+1)*sizeof(nt_forms_struct))) == NULL)
171 unistr2_to_ascii((*list)[n].name, &(form->name), sizeof((*list)[n].name)-1);
175 (*list)[n].flag=form->flags;
176 (*list)[n].width=form->size_x;
177 (*list)[n].length=form->size_y;
178 (*list)[n].left=form->left;
179 (*list)[n].top=form->top;
180 (*list)[n].right=form->right;
181 (*list)[n].bottom=form->bottom;
186 /****************************************************************************
188 ****************************************************************************/
189 void update_a_form(nt_forms_struct **list, const FORM *form, int count)
193 unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
195 DEBUG(106, ("[%s]\n", form_name));
196 for (n=0; n<count; n++)
198 DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
199 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
203 if (n==count) return;
205 (*list)[n].flag=form->flags;
206 (*list)[n].width=form->size_x;
207 (*list)[n].length=form->size_y;
208 (*list)[n].left=form->left;
209 (*list)[n].top=form->top;
210 (*list)[n].right=form->right;
211 (*list)[n].bottom=form->bottom;
214 /****************************************************************************
215 get the nt drivers list
217 traverse the database and look-up the matching names
218 ****************************************************************************/
219 int get_ntdrivers(fstring **list, char *architecture)
224 TDB_DATA kbuf, newkey;
226 get_short_archi(short_archi, architecture);
227 slprintf(key, sizeof(key), "%s%s/", DRIVERS_PREFIX, short_archi);
229 for (kbuf = tdb_firstkey(tdb);
231 newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
232 if (strncmp(kbuf.dptr, key, strlen(key)) != 0) continue;
234 if((*list = Realloc(*list, sizeof(fstring)*(total+1))) == NULL)
237 fstrcpy((*list)[total], kbuf.dptr+strlen(key));
244 /****************************************************************************
245 function to do the mapping between the long architecture name and
247 ****************************************************************************/
248 void get_short_archi(char *short_archi, char *long_archi)
255 struct table archi_table[]=
257 {"Windows 4.0", "WIN40" },
258 {"Windows NT x86", "W32X86" },
259 {"Windows NT R4000", "W32mips" },
260 {"Windows NT Alpha_AXP", "W32alpha" },
261 {"Windows NT PowerPC", "W32ppc" },
267 DEBUG(107,("Getting architecture dependant directory\n"));
270 } while ( (archi_table[i].long_archi!=NULL ) && strncmp(long_archi, archi_table[i].long_archi, strlen(long_archi)) );
272 if (archi_table[i].long_archi==NULL)
274 DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
276 StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
278 DEBUGADD(108,("index: [%d]\n", i));
279 DEBUGADD(108,("long architecture: [%s]\n", long_archi));
280 DEBUGADD(108,("short architecture: [%s]\n", short_archi));
283 /****************************************************************************
284 ****************************************************************************/
285 static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
288 fstring architecture;
294 get_short_archi(architecture, driver->environment);
295 slprintf(key, sizeof(key), "%s%s/%s", DRIVERS_PREFIX, architecture, driver->name);
298 * cversion must be 2.
299 * when adding a printer ON the SERVER
300 * rpcAddPrinterDriver defines it to zero
312 len += tdb_pack(buf+len, buflen-len, "dffffffff",
321 driver->defaultdatatype);
323 if (driver->dependentfiles) {
324 for (i=0; *driver->dependentfiles[i]; i++) {
325 len += tdb_pack(buf+len, buflen-len, "f",
326 driver->dependentfiles[i]);
331 buf = (char *)Realloc(buf, len);
338 kbuf.dsize = strlen(key)+1;
342 ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
348 /****************************************************************************
349 ****************************************************************************/
350 static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
352 NT_PRINTER_DRIVER_INFO_LEVEL_3 info3;
355 info3.cversion = driver->version;
356 fstrcpy(info3.environment,driver->environment);
357 fstrcpy(info3.driverpath,driver->driverpath);
358 fstrcpy(info3.datafile,driver->datafile);
359 fstrcpy(info3.configfile,driver->configfile);
360 fstrcpy(info3.helpfile,driver->helpfile);
361 fstrcpy(info3.monitorname,driver->monitorname);
362 fstrcpy(info3.defaultdatatype,driver->defaultdatatype);
363 info3.dependentfiles = driver->dependentfiles;
365 return add_a_printer_driver_3(&info3);
369 /****************************************************************************
370 ****************************************************************************/
371 static uint32 get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
373 NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
377 fstrcpy(info.name, in_prt);
378 fstrcpy(info.defaultdatatype, "RAW");
380 fstrcpy(info.driverpath, "");
381 fstrcpy(info.datafile, "");
382 fstrcpy(info.configfile, "");
383 fstrcpy(info.helpfile, "");
385 if ((info.dependentfiles=(fstring *)malloc(2*sizeof(fstring))) == NULL)
386 return ERROR_NOT_ENOUGH_MEMORY;
388 memset(info.dependentfiles, '\0', 2*sizeof(fstring));
389 fstrcpy(info.dependentfiles[0], "");
391 *info_ptr = memdup(&info, sizeof(info));
396 /****************************************************************************
397 ****************************************************************************/
398 static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
400 NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
402 fstring architecture;
409 get_short_archi(architecture, in_arch);
410 slprintf(key, sizeof(key), "%s%s/%s", DRIVERS_PREFIX, architecture, in_prt);
413 kbuf.dsize = strlen(key)+1;
415 dbuf = tdb_fetch(tdb, kbuf);
416 if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
418 len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff",
427 driver.defaultdatatype);
430 while (len < dbuf.dsize) {
431 driver.dependentfiles = (fstring *)Realloc(driver.dependentfiles,
432 sizeof(fstring)*(i+2));
433 if (driver.dependentfiles == NULL)
436 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f",
437 &driver.dependentfiles[i]);
440 if (driver.dependentfiles != NULL)
441 fstrcpy(driver.dependentfiles[i], "");
443 safe_free(dbuf.dptr);
445 if (len != dbuf.dsize) {
446 if (driver.dependentfiles != NULL)
447 safe_free(driver.dependentfiles);
449 return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
452 *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
457 /****************************************************************************
458 debugging function, dump at level 6 the struct in the logs
459 ****************************************************************************/
460 static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
463 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
466 DEBUG(106,("Dumping printer driver at level [%d]\n", level));
472 if (driver.info_3 == NULL)
477 DEBUGADD(106,("version:[%d]\n", info3->cversion));
478 DEBUGADD(106,("name:[%s]\n", info3->name));
479 DEBUGADD(106,("environment:[%s]\n", info3->environment));
480 DEBUGADD(106,("driverpath:[%s]\n", info3->driverpath));
481 DEBUGADD(106,("datafile:[%s]\n", info3->datafile));
482 DEBUGADD(106,("configfile:[%s]\n", info3->configfile));
483 DEBUGADD(106,("helpfile:[%s]\n", info3->helpfile));
484 DEBUGADD(106,("monitorname:[%s]\n", info3->monitorname));
485 DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
487 for (i=0; info3->dependentfiles &&
488 *info3->dependentfiles[i]; i++) {
489 DEBUGADD(106,("dependentfile:[%s]\n",
490 info3->dependentfiles[i]));
497 DEBUGADD(1,("Level not implemented\n"));
505 /****************************************************************************
506 ****************************************************************************/
507 static int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
511 len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
513 if (!nt_devmode) return len;
515 len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
516 nt_devmode->devicename,
517 nt_devmode->formname,
519 nt_devmode->specversion,
520 nt_devmode->driverversion,
522 nt_devmode->driverextra,
523 nt_devmode->orientation,
524 nt_devmode->papersize,
525 nt_devmode->paperlength,
526 nt_devmode->paperwidth,
529 nt_devmode->defaultsource,
530 nt_devmode->printquality,
533 nt_devmode->yresolution,
534 nt_devmode->ttoption,
536 nt_devmode->logpixels,
539 nt_devmode->bitsperpel,
540 nt_devmode->pelswidth,
541 nt_devmode->pelsheight,
542 nt_devmode->displayflags,
543 nt_devmode->displayfrequency,
544 nt_devmode->icmmethod,
545 nt_devmode->icmintent,
546 nt_devmode->mediatype,
547 nt_devmode->dithertype,
548 nt_devmode->reserved1,
549 nt_devmode->reserved2,
550 nt_devmode->panningwidth,
551 nt_devmode->panningheight,
552 nt_devmode->private);
555 if (nt_devmode->private) {
556 len += tdb_pack(buf+len, buflen-len, "B",
557 nt_devmode->driverextra,
558 nt_devmode->private);
561 DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname));
566 /****************************************************************************
567 ****************************************************************************/
568 static int pack_specifics(NT_PRINTER_PARAM *param, char *buf, int buflen)
572 while (param != NULL) {
573 len += tdb_pack(buf+len, buflen-len, "pfdB",
582 len += tdb_pack(buf+len, buflen-len, "p", param);
588 /****************************************************************************
589 delete a printer - this just deletes the printer info file, any open
590 handles are not affected
591 ****************************************************************************/
592 uint32 del_a_printer(char *portname)
597 slprintf(key, sizeof(key), "%s%s",
598 PRINTERS_PREFIX, portname);
601 kbuf.dsize=strlen(key)+1;
603 tdb_delete(tdb, kbuf);
607 /****************************************************************************
608 ****************************************************************************/
609 static uint32 add_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
613 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.
643 unix_to_nt_time(&time_nt, time_unix);
644 info->changeid=time_nt.low;
645 info->c_setprinter++;
652 len += tdb_pack(buf+len, buflen-len, "dddddddddddffffffffff",
655 info->default_priority,
671 info->printprocessor,
675 len += pack_devicemode(info->devmode, buf+len, buflen-len);
676 len += pack_specifics(info->specific, buf+len, buflen-len);
679 buf = (char *)Realloc(buf, len);
685 slprintf(key, sizeof(key), "%s%s",
686 PRINTERS_PREFIX, info->sharename);
689 kbuf.dsize = strlen(key)+1;
693 ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
696 DEBUG(8, ("error updating printer to tdb on disk\n"));
700 DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n",
701 info->portname, info->drivername, info->portname, len));
707 /****************************************************************************
708 ****************************************************************************/
709 BOOL add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
711 NT_PRINTER_PARAM *current;
713 DEBUG(108,("add_a_specific_param\n"));
717 if (info_2->specific == NULL)
719 info_2->specific=param;
723 current=info_2->specific;
724 while (current->next != NULL) {
725 current=current->next;
732 /****************************************************************************
733 ****************************************************************************/
734 BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
736 NT_PRINTER_PARAM *current;
737 NT_PRINTER_PARAM *previous;
739 current=info_2->specific;
742 if (current==NULL) return (False);
744 if ( !strcmp(current->value, param->value) &&
745 (strlen(current->value)==strlen(param->value)) ) {
746 DEBUG(109,("deleting first value\n"));
747 info_2->specific=current->next;
748 safe_free(current->data);
750 DEBUG(109,("deleted first value\n"));
754 current=previous->next;
756 while ( current!=NULL ) {
757 if (!strcmp(current->value, param->value) &&
758 strlen(current->value)==strlen(param->value) ) {
759 DEBUG(109,("deleting current value\n"));
760 previous->next=current->next;
761 safe_free(current->data);
763 DEBUG(109,("deleted current value\n"));
767 previous=previous->next;
768 current=current->next;
773 /****************************************************************************
774 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
775 ****************************************************************************/
776 static void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr)
778 NT_PRINTER_PARAM *param = *param_ptr;
783 DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param->value));
786 safe_free(param->data);
792 /****************************************************************************
793 Malloc and return an NT devicemode.
794 ****************************************************************************/
796 NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
799 * should I init this ones ???
800 nt_devmode->devicename
804 NT_DEVICEMODE *nt_devmode = (NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE));
806 if (nt_devmode == NULL) {
807 DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
811 ZERO_STRUCTP(nt_devmode);
813 snprintf(adevice, sizeof(adevice), "\\\\%s\\%s", global_myname, default_devicename);
814 fstrcpy(nt_devmode->devicename, adevice);
817 fstrcpy(nt_devmode->formname, "Letter");
819 nt_devmode->specversion = 0x0401;
820 nt_devmode->driverversion = 0x0400;
821 nt_devmode->size = 0x00DC;
822 nt_devmode->driverextra = 0x0000;
823 nt_devmode->fields = FORMNAME | TTOPTION | PRINTQUALITY |
824 DEFAULTSOURCE | COPIES | SCALE |
825 PAPERSIZE | ORIENTATION;
826 nt_devmode->orientation = 1;
827 nt_devmode->papersize = PAPER_LETTER;
828 nt_devmode->paperlength = 0;
829 nt_devmode->paperwidth = 0;
830 nt_devmode->scale = 0x64;
831 nt_devmode->copies = 01;
832 nt_devmode->defaultsource = BIN_FORMSOURCE;
833 nt_devmode->printquality = 0x0258;
834 nt_devmode->color = COLOR_MONOCHROME;
835 nt_devmode->duplex = DUP_SIMPLEX;
836 nt_devmode->yresolution = 0;
837 nt_devmode->ttoption = TT_SUBDEV;
838 nt_devmode->collate = COLLATE_FALSE;
839 nt_devmode->icmmethod = 0;
840 nt_devmode->icmintent = 0;
841 nt_devmode->mediatype = 0;
842 nt_devmode->dithertype = 0;
844 /* non utilisés par un driver d'imprimante */
845 nt_devmode->logpixels = 0;
846 nt_devmode->bitsperpel = 0;
847 nt_devmode->pelswidth = 0;
848 nt_devmode->pelsheight = 0;
849 nt_devmode->displayflags = 0;
850 nt_devmode->displayfrequency = 0;
851 nt_devmode->reserved1 = 0;
852 nt_devmode->reserved2 = 0;
853 nt_devmode->panningwidth = 0;
854 nt_devmode->panningheight = 0;
856 nt_devmode->private=NULL;
861 /****************************************************************************
862 Deepcopy an NT devicemode.
863 ****************************************************************************/
865 NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
867 NT_DEVICEMODE *new_nt_devicemode = NULL;
869 if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
870 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
874 new_nt_devicemode->private = NULL;
875 if (nt_devicemode->private != NULL) {
876 if ((new_nt_devicemode->private = memdup(nt_devicemode->private, nt_devicemode->driverextra)) == NULL) {
877 safe_free(new_nt_devicemode);
878 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
883 return new_nt_devicemode;
886 /****************************************************************************
887 Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
888 ****************************************************************************/
890 void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
892 NT_DEVICEMODE *nt_devmode = *devmode_ptr;
894 if(nt_devmode == NULL)
897 DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
899 if(nt_devmode->private)
900 safe_free(nt_devmode->private);
902 safe_free(nt_devmode);
906 /****************************************************************************
907 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
908 ****************************************************************************/
909 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
911 NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
912 NT_PRINTER_PARAM *param_ptr;
917 DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
919 free_nt_devicemode(&info->devmode);
920 free_sec_desc_buf(&info->secdesc_buf);
922 for(param_ptr = info->specific; param_ptr; ) {
923 NT_PRINTER_PARAM *tofree = param_ptr;
925 param_ptr = param_ptr->next;
926 free_nt_printer_param(&tofree);
929 safe_free(*info_ptr);
934 /****************************************************************************
935 ****************************************************************************/
936 static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
939 NT_DEVICEMODE devmode;
941 ZERO_STRUCT(devmode);
943 len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
945 if (!*nt_devmode) return len;
947 len += tdb_unpack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
951 &devmode.specversion,
952 &devmode.driverversion,
954 &devmode.driverextra,
955 &devmode.orientation,
957 &devmode.paperlength,
961 &devmode.defaultsource,
962 &devmode.printquality,
965 &devmode.yresolution,
974 &devmode.displayflags,
975 &devmode.displayfrequency,
982 &devmode.panningwidth,
983 &devmode.panningheight,
987 len += tdb_unpack(buf+len, buflen-len, "B", &devmode.driverextra, &devmode.private);
989 *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
991 DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode.devicename, devmode.formname));
993 DEBUG(8,("with a private section of %d bytes\n", devmode.driverextra));
998 /****************************************************************************
999 ****************************************************************************/
1000 static int unpack_specifics(NT_PRINTER_PARAM **list, char *buf, int buflen)
1003 NT_PRINTER_PARAM param, *p;
1008 len += tdb_unpack(buf+len, buflen-len, "p", &p);
1011 len += tdb_unpack(buf+len, buflen-len, "fdB",
1017 *list = memdup(¶m, sizeof(param));
1024 /****************************************************************************
1025 get a default printer info 2 struct
1026 ****************************************************************************/
1027 static uint32 get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
1029 extern pstring global_myname;
1031 NT_PRINTER_INFO_LEVEL_2 info;
1035 snum = lp_servicenumber(sharename);
1037 fstrcpy(info.servername, global_myname);
1038 fstrcpy(info.printername, sharename);
1039 fstrcpy(info.portname, sharename);
1040 fstrcpy(info.drivername, lp_printerdriver(snum));
1041 fstrcpy(info.printprocessor, "winprint");
1042 fstrcpy(info.datatype, "RAW");
1044 info.attributes = PRINTER_ATTRIBUTE_SHARED \
1045 | PRINTER_ATTRIBUTE_LOCAL \
1046 | PRINTER_ATTRIBUTE_RAW_ONLY ; /* attributes */
1048 info.starttime = 0; /* Minutes since 12:00am GMT */
1049 info.untiltime = 0; /* Minutes since 12:00am GMT */
1051 info.default_priority = 1;
1053 if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
1056 if (!nt_printing_getsec(sharename, &info.secdesc_buf))
1059 *info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
1061 DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
1070 free_nt_devicemode(&info.devmode);
1071 if (info.secdesc_buf)
1072 free_sec_desc_buf(&info.secdesc_buf);
1076 /****************************************************************************
1077 ****************************************************************************/
1078 static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
1081 NT_PRINTER_INFO_LEVEL_2 info;
1083 TDB_DATA kbuf, dbuf;
1087 slprintf(key, sizeof(key), "%s%s",
1088 PRINTERS_PREFIX, sharename);
1091 kbuf.dsize = strlen(key)+1;
1093 dbuf = tdb_fetch(tdb, kbuf);
1095 if (!dbuf.dptr) return get_a_printer_2_default(info_ptr, sharename);
1097 if (!dbuf.dptr) return 1;
1100 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddffffffffff",
1103 &info.default_priority,
1119 info.printprocessor,
1123 info.attributes |= PRINTER_ATTRIBUTE_RAW_ONLY; /* Samba has to have raw drivers. */
1125 len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
1126 len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
1129 nt_printing_getsec(sharename, &info.secdesc_buf);
1130 #endif /* JRATEST */
1132 fstrcpy(info.sharename, "");
1134 safe_free(dbuf.dptr);
1135 *info_ptr=memdup(&info, sizeof(info));
1137 DEBUG(9,("Unpacked printer [%s] running drier [%s]\n",
1138 sharename, info.drivername));
1144 /****************************************************************************
1145 debugging function, dump at level 6 the struct in the logs
1146 ****************************************************************************/
1147 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1150 NT_PRINTER_INFO_LEVEL_2 *info2;
1152 DEBUG(106,("Dumping printer at level [%d]\n", level));
1158 if (printer.info_2 == NULL)
1162 info2=printer.info_2;
1164 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
1165 DEBUGADD(106,("priority:[%d]\n", info2->priority));
1166 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
1167 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
1168 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
1169 DEBUGADD(106,("status:[%d]\n", info2->status));
1170 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
1171 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
1172 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
1173 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
1174 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
1176 DEBUGADD(106,("servername:[%s]\n", info2->servername));
1177 DEBUGADD(106,("printername:[%s]\n", info2->printername));
1178 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
1179 DEBUGADD(106,("portname:[%s]\n", info2->portname));
1180 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
1181 DEBUGADD(106,("location:[%s]\n", info2->location));
1182 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
1183 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
1184 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
1185 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
1191 DEBUGADD(1,("Level not implemented\n"));
1200 * The function below are the high level ones.
1201 * only those ones must be called from the spoolss code.
1206 /****************************************************************************
1207 ****************************************************************************/
1208 uint32 add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1212 dump_a_printer(printer, level);
1218 success=add_a_printer_2(printer.info_2);
1229 /****************************************************************************
1230 Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
1231 ****************************************************************************/
1233 uint32 get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename)
1236 NT_PRINTER_INFO_LEVEL *printer = NULL;
1240 DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
1246 if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
1247 DEBUG(0,("get_a_printer: malloc fail.\n"));
1250 ZERO_STRUCTP(printer);
1251 success=get_a_printer_2(&printer->info_2, sharename);
1253 dump_a_printer(*printer, level);
1254 *pp_printer = printer;
1265 DEBUG(10,("get_a_printer: [%s] level %u returning %u\n", sharename, (unsigned int)level, (unsigned int)success));
1270 /****************************************************************************
1271 Deletes a NT_PRINTER_INFO_LEVEL struct.
1272 ****************************************************************************/
1274 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
1277 NT_PRINTER_INFO_LEVEL *printer = *pp_printer;
1279 DEBUG(104,("freeing a printer at level [%d]\n", level));
1281 if (printer == NULL)
1288 if (printer->info_2 != NULL)
1290 free_nt_printer_info_level_2(&printer->info_2);
1309 /****************************************************************************
1310 ****************************************************************************/
1311 uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1314 DEBUG(104,("adding a printer at level [%d]\n", level));
1315 dump_a_printer_driver(driver, level);
1321 success=add_a_printer_driver_3(driver.info_3);
1327 success=add_a_printer_driver_6(driver.info_6);
1337 /****************************************************************************
1338 ****************************************************************************/
1339 uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
1340 fstring printername, fstring architecture)
1348 success=get_a_printer_driver_3(&(driver->info_3),
1358 if (success == 0) dump_a_printer_driver(*driver, level);
1362 /****************************************************************************
1363 ****************************************************************************/
1364 uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1372 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1373 if (driver.info_3 != NULL)
1375 info3=driver.info_3;
1376 safe_free(info3->dependentfiles);
1377 ZERO_STRUCTP(info3);
1389 NT_PRINTER_DRIVER_INFO_LEVEL_6 *info6;
1390 if (driver.info_6 != NULL)
1392 info6=driver.info_6;
1393 safe_free(info6->dependentfiles);
1394 safe_free(info6->previousnames);
1395 ZERO_STRUCTP(info6);
1412 /****************************************************************************
1413 ****************************************************************************/
1414 BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
1415 fstring value, uint8 **data, uint32 *type, uint32 *len)
1417 /* right now that's enough ! */
1418 NT_PRINTER_PARAM *param;
1421 param=printer.info_2->specific;
1423 while (param != NULL && i < param_index) {
1431 /* exited because it exist */
1433 StrnCpy(value, param->value, sizeof(fstring)-1);
1434 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
1437 ZERO_STRUCTP(*data);
1438 memcpy(*data, param->data, param->data_len);
1439 *len=param->data_len;
1443 /****************************************************************************
1444 ****************************************************************************/
1445 BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level,
1446 fstring value, uint8 **data, uint32 *type, uint32 *len)
1448 /* right now that's enough ! */
1449 NT_PRINTER_PARAM *param;
1451 DEBUG(105, ("get_specific_param\n"));
1453 param=printer.info_2->specific;
1455 while (param != NULL)
1457 if ( !strcmp(value, param->value)
1458 && strlen(value)==strlen(param->value))
1464 DEBUG(106, ("found one param\n"));
1467 /* exited because it exist */
1470 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
1473 memcpy(*data, param->data, param->data_len);
1474 *len=param->data_len;
1476 DEBUG(106, ("exit of get_specific_param:true\n"));
1479 DEBUG(106, ("exit of get_specific_param:false\n"));
1484 /****************************************************************************
1485 store a security desc for a printer
1486 ****************************************************************************/
1487 uint32 nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
1489 SEC_DESC_BUF *new_secdesc_ctr = NULL;
1490 SEC_DESC_BUF *old_secdesc_ctr = NULL;
1495 /* The old owner and group sids of the security descriptor are not
1496 present when new ACEs are added or removed by changing printer
1497 permissions through NT. If they are NULL in the new security
1498 descriptor then copy them over from the old one. */
1500 if (!secdesc_ctr->sec->owner_sid || !secdesc_ctr->sec->grp_sid) {
1501 DOM_SID *owner_sid, *group_sid;
1502 SEC_DESC *psd = NULL;
1505 /* Pick out correct owner and group sids */
1507 owner_sid = secdesc_ctr->sec->owner_sid ?
1508 secdesc_ctr->sec->owner_sid :
1509 old_secdesc_ctr->sec->owner_sid;
1511 group_sid = secdesc_ctr->sec->grp_sid ?
1512 secdesc_ctr->sec->grp_sid :
1513 old_secdesc_ctr->sec->grp_sid;
1515 /* Make a deep copy of the security descriptor */
1517 psd = make_sec_desc(secdesc_ctr->sec->revision,
1518 secdesc_ctr->sec->type,
1519 owner_sid, group_sid,
1520 secdesc_ctr->sec->sacl,
1521 secdesc_ctr->sec->dacl,
1524 new_secdesc_ctr = make_sec_desc_buf(size, psd);
1526 /* Free up memory */
1528 free_sec_desc(&psd);
1531 if (!new_secdesc_ctr) {
1532 new_secdesc_ctr = secdesc_ctr;
1535 /* Store the security descriptor in a tdb */
1537 prs_init(&ps, (uint32)sec_desc_size(new_secdesc_ctr->sec) +
1538 sizeof(SEC_DESC_BUF), 4, MARSHALL);
1540 if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr,
1542 status = ERROR_INVALID_FUNCTION;
1546 slprintf(key, sizeof(key), "SECDESC/%s", printername);
1548 if (tdb_prs_store(tdb, key, &ps)==0) {
1551 DEBUG(1,("Failed to store secdesc for %s\n", printername));
1552 status = ERROR_INVALID_FUNCTION;
1555 /* Free mallocated memory */
1558 free_sec_desc_buf(&old_secdesc_ctr);
1560 if (new_secdesc_ctr != secdesc_ctr) {
1561 free_sec_desc_buf(&new_secdesc_ctr);
1568 /****************************************************************************
1569 Construct a default security descriptor buffer for a printer.
1570 ****************************************************************************/
1572 static SEC_DESC_BUF *construct_default_printer_sdb(void)
1576 SEC_ACL *psa = NULL;
1577 SEC_DESC_BUF *sdb = NULL;
1578 SEC_DESC *psd = NULL;
1583 /* Create an ACE where Everyone is allowed to print */
1585 init_sec_access(&sa, PRINTER_ACE_PRINT);
1586 init_sec_ace(&ace, &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
1587 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
1589 /* Make the security descriptor owned by the Administrators group
1590 on the PDC of the domain. */
1592 if (winbind_lookup_name(lp_workgroup(), &owner_sid, &name_type)) {
1593 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
1596 /* Backup plan - make printer owned by world. This should
1597 emulate a lanman printer as security settings can't be
1600 sid_copy(&owner_sid, &global_sid_World);
1603 /* The ACL revision number in rpc_secdesc.h differs from the one
1604 created by NT when setting ACE entries in printer
1605 descriptors. NT4 complains about the property being edited by a
1608 #define NT4_ACL_REVISION 0x2
1610 if ((psa = make_sec_acl(NT4_ACL_REVISION, 1, &ace)) != NULL) {
1611 psd = make_sec_desc(SEC_DESC_REVISION,
1612 SEC_DESC_SELF_RELATIVE |
1613 SEC_DESC_DACL_PRESENT,
1615 NULL, psa, &sd_size);
1620 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
1624 sdb = make_sec_desc_buf(sd_size, psd);
1626 DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
1627 (unsigned int)sd_size));
1629 free_sec_desc(&psd);
1633 /****************************************************************************
1634 Get a security desc for a printer.
1635 ****************************************************************************/
1637 BOOL nt_printing_getsec(char *printername, SEC_DESC_BUF **secdesc_ctr)
1642 /* Fetch security descriptor from tdb */
1644 slprintf(key, sizeof(key), "SECDESC/%s", printername);
1646 if (tdb_prs_fetch(tdb, key, &ps)!=0 ||
1647 !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
1649 DEBUG(4,("using default secdesc for %s\n", printername));
1651 if (!(*secdesc_ctr = construct_default_printer_sdb()))
1657 /* If security descriptor is owned by S-1-1-0 and winbindd is up,
1658 this security descriptor has been created when winbindd was
1659 down. Take ownership of security descriptor. */
1661 if (sid_equal((*secdesc_ctr)->sec->owner_sid, &global_sid_World)) {
1665 /* Change sd owner to workgroup administrator */
1667 if (winbind_lookup_name(lp_workgroup(), &owner_sid,
1669 SEC_DESC_BUF *new_secdesc_ctr = NULL;
1670 SEC_DESC *psd = NULL;
1675 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
1677 psd = make_sec_desc((*secdesc_ctr)->sec->revision,
1678 (*secdesc_ctr)->sec->type,
1680 (*secdesc_ctr)->sec->grp_sid,
1681 (*secdesc_ctr)->sec->sacl,
1682 (*secdesc_ctr)->sec->dacl,
1685 new_secdesc_ctr = make_sec_desc_buf(size, psd);
1687 free_sec_desc(&psd);
1689 /* Swap with other one */
1691 free_sec_desc_buf(secdesc_ctr);
1692 *secdesc_ctr = new_secdesc_ctr;
1696 nt_printing_setsec(printername, *secdesc_ctr);
1706 1: level not implemented
1707 2: file doesn't exist
1708 3: can't allocate memory
1709 4: can't free memory
1710 5: non existant struct
1714 A printer and a printer driver are 2 different things.
1715 NT manages them separatelly, Samba does the same.
1716 Why ? Simply because it's easier and it makes sense !
1718 Now explanation: You have 3 printers behind your samba server,
1719 2 of them are the same make and model (laser A and B). But laser B
1720 has an 3000 sheet feeder and laser A doesn't such an option.
1721 Your third printer is an old dot-matrix model for the accounting :-).
1723 If the /usr/local/samba/lib directory (default dir), you will have
1724 5 files to describe all of this.
1726 3 files for the printers (1 by printer):
1729 NTprinter_accounting
1730 2 files for the drivers (1 for the laser and 1 for the dot matrix)
1731 NTdriver_printer model X
1732 NTdriver_printer model Y
1734 jfm: I should use this comment for the text file to explain
1735 same thing for the forms BTW.
1736 Je devrais mettre mes commentaires en francais, ca serait mieux :-)
1740 /* Check a user has permissions to perform the given operation */
1742 BOOL print_access_check(struct current_user *user, int snum,
1743 uint32 required_access)
1745 SEC_DESC_BUF *secdesc = NULL;
1746 uint32 access_granted, status;
1751 /* Get printer name */
1753 pname = PRINTERNAME(snum);
1754 if (!pname || !*pname) pname = SERVICE(snum);
1756 /* Get printer security descriptor */
1758 nt_printing_getsec(pname, &secdesc);
1760 /* The ACE for Full Control in a printer security descriptor
1761 doesn't seem to map properly to the access checking model. For
1762 it to work properly it should be the logical OR of all the other
1763 values, i.e PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT.
1764 This would cause the access check to simply fall out when we
1765 check against any subset of these bits. To get things to work,
1766 change every ACE mask of PRINTER_ACE_FULL_CONTROL to
1767 PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT before
1768 performing the access check. I'm sure there is a better way to
1771 if (secdesc && secdesc->sec && secdesc->sec->dacl &&
1772 secdesc->sec->dacl->ace) {
1773 for(i = 0; i < secdesc->sec->dacl->num_aces; i++) {
1774 if (secdesc->sec->dacl->ace[i].info.mask ==
1775 PRINTER_ACE_FULL_CONTROL) {
1776 secdesc->sec->dacl->ace[i].info.mask =
1777 PRINTER_ACE_MANAGE_DOCUMENTS |
1785 result = se_access_check(secdesc->sec, user, required_access,
1786 &access_granted, &status);
1788 DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE"));
1790 /* Free mallocated memory */
1792 free_sec_desc_buf(&secdesc);