3 * Unix SMB/Netbios implementation.
5 * RPC Pipe client / server routines
6 * Copyright (C) Andrew Tridgell 1992-2000,
7 * Copyright (C) Jean François Micouleau 1998-2000.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 extern int DEBUGLEVEL;
27 extern pstring global_myname;
28 extern DOM_SID global_sid_World;
30 static TDB_CONTEXT *tdb; /* used for driver files */
32 #define FORMS_PREFIX "FORMS/"
33 #define DRIVERS_PREFIX "DRIVERS/"
34 #define PRINTERS_PREFIX "PRINTERS/"
36 #define DATABASE_VERSION 1
38 /* we need to have a small set of default forms to support our
40 static nt_forms_struct default_forms[] = {
41 {"Letter", 0x2, 0x34b5b, 0x44367, 0x0, 0x0, 0x34b5b, 0x44367},
42 {"A4", 0x2, 0x3354f, 0x4884e, 0x0, 0x0, 0x3354f, 0x4884e}
46 /****************************************************************************
47 open the NT printing tdb
48 ****************************************************************************/
49 BOOL nt_printing_init(void)
51 static pid_t local_pid;
53 if (tdb && local_pid == sys_getpid()) return True;
54 tdb = tdb_open(lock_path("ntdrivers.tdb"), 0, 0, O_RDWR|O_CREAT, 0600);
56 DEBUG(0,("Failed to open nt drivers database\n"));
60 local_pid = sys_getpid();
62 /* handle a Samba upgrade */
64 if (tdb_fetch_int(tdb, "INFO/version") != DATABASE_VERSION) {
65 tdb_traverse(tdb, (tdb_traverse_func)tdb_delete, NULL);
66 tdb_store_int(tdb, "INFO/version", DATABASE_VERSION);
74 /****************************************************************************
75 get a form struct list
76 ****************************************************************************/
77 int get_ntforms(nt_forms_struct **list)
79 TDB_DATA kbuf, newkey, dbuf;
84 for (kbuf = tdb_firstkey(tdb);
86 newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
87 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0) continue;
89 dbuf = tdb_fetch(tdb, kbuf);
90 if (!dbuf.dptr) continue;
92 fstrcpy(form.name, kbuf.dptr+strlen(FORMS_PREFIX));
93 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddddddd",
94 &form.flag, &form.width, &form.length, &form.left,
95 &form.top, &form.right, &form.bottom);
97 if (ret != dbuf.dsize) continue;
99 *list = Realloc(*list, sizeof(nt_forms_struct)*(n+1));
104 /* we should never return a null forms list or NT gets unhappy */
106 *list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));
107 n = sizeof(default_forms) / sizeof(default_forms[0]);
114 /****************************************************************************
115 write a form struct list
116 ****************************************************************************/
117 int write_ntforms(nt_forms_struct **list, int number)
124 for (i=0;i<number;i++) {
125 len = tdb_pack(buf, sizeof(buf), "ddddddd",
126 (*list)[i].flag, (*list)[i].width, (*list)[i].length,
127 (*list)[i].left, (*list)[i].top, (*list)[i].right,
129 if (len > sizeof(buf)) break;
130 slprintf(key, sizeof(key), "%s%s", FORMS_PREFIX, (*list)[i].name);
131 kbuf.dsize = strlen(key)+1;
135 if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) break;
141 /****************************************************************************
142 add a form struct at the end of the list
143 ****************************************************************************/
144 BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
151 * NT tries to add forms even when
152 * they are already in the base
153 * only update the values if already present
158 unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
159 for (n=0; n<*count && update==False; n++)
161 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
163 DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
170 if((*list=Realloc(*list, (n+1)*sizeof(nt_forms_struct))) == NULL)
172 unistr2_to_ascii((*list)[n].name, &(form->name), sizeof((*list)[n].name)-1);
176 (*list)[n].flag=form->flags;
177 (*list)[n].width=form->size_x;
178 (*list)[n].length=form->size_y;
179 (*list)[n].left=form->left;
180 (*list)[n].top=form->top;
181 (*list)[n].right=form->right;
182 (*list)[n].bottom=form->bottom;
187 /****************************************************************************
189 ****************************************************************************/
190 void update_a_form(nt_forms_struct **list, const FORM *form, int count)
194 unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
196 DEBUG(106, ("[%s]\n", form_name));
197 for (n=0; n<count; n++)
199 DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
200 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
204 if (n==count) return;
206 (*list)[n].flag=form->flags;
207 (*list)[n].width=form->size_x;
208 (*list)[n].length=form->size_y;
209 (*list)[n].left=form->left;
210 (*list)[n].top=form->top;
211 (*list)[n].right=form->right;
212 (*list)[n].bottom=form->bottom;
215 /****************************************************************************
216 get the nt drivers list
218 traverse the database and look-up the matching names
219 ****************************************************************************/
220 int get_ntdrivers(fstring **list, char *architecture, uint32 version)
225 TDB_DATA kbuf, newkey;
227 get_short_archi(short_archi, architecture);
228 slprintf(key, sizeof(key), "%s%s/%d/", DRIVERS_PREFIX, short_archi, version);
230 for (kbuf = tdb_firstkey(tdb);
232 newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
233 if (strncmp(kbuf.dptr, key, strlen(key)) != 0) continue;
235 if((*list = Realloc(*list, sizeof(fstring)*(total+1))) == NULL)
238 fstrcpy((*list)[total], kbuf.dptr+strlen(key));
245 /****************************************************************************
246 function to do the mapping between the long architecture name and
248 ****************************************************************************/
249 BOOL get_short_archi(char *short_archi, char *long_archi)
256 struct table archi_table[]=
258 {"Windows 4.0", "WIN40" },
259 {"Windows NT x86", "W32X86" },
260 {"Windows NT R4000", "W32MIPS" },
261 {"Windows NT Alpha_AXP", "W32ALPHA" },
262 {"Windows NT PowerPC", "W32PPC" },
268 DEBUG(107,("Getting architecture dependant directory\n"));
271 } while ( (archi_table[i].long_archi!=NULL ) &&
272 StrCaseCmp(long_archi, archi_table[i].long_archi) );
274 if (archi_table[i].long_archi==NULL) {
275 DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
279 StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
281 DEBUGADD(108,("index: [%d]\n", i));
282 DEBUGADD(108,("long architecture: [%s]\n", long_archi));
283 DEBUGADD(108,("short architecture: [%s]\n", short_archi));
288 /****************************************************************************
289 ****************************************************************************/
290 static void clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
292 fstring architecture;
297 /* jfm:7/16/2000 the client always sends the cversion=0.
298 * The server should check which version the driver is by reading the PE header
299 * of driver->driverpath.
301 * For Windows 95/98 the version is 0 (so the value sent is correct)
302 * For Windows NT (the architecture doesn't matter)
304 * NT 3.5/3.51: cversion=1
309 get_short_archi(architecture, driver->environment);
311 /* if it's Windows 95/98, we keep the version at 0
312 * jfmxxx: I need to redo that more correctly for NT2K.
315 if (StrCaseCmp(driver->environment, "Windows 4.0")==0)
320 /* clean up the driver name.
321 * we can get .\driver.dll
322 * or worse c:\windows\system\driver.dll !
324 /* using an intermediate string to not have overlaping memcpy()'s */
325 if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
326 fstrcpy(new_name, p+1);
327 fstrcpy(driver->driverpath, new_name);
330 if ((p = strrchr(driver->datafile,'\\')) != NULL) {
331 fstrcpy(new_name, p+1);
332 fstrcpy(driver->datafile, new_name);
335 if ((p = strrchr(driver->configfile,'\\')) != NULL) {
336 fstrcpy(new_name, p+1);
337 fstrcpy(driver->configfile, new_name);
340 if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
341 fstrcpy(new_name, p+1);
342 fstrcpy(driver->helpfile, new_name);
345 if (driver->dependentfiles) {
346 for (i=0; *driver->dependentfiles[i]; i++) {
347 if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
348 fstrcpy(new_name, p+1);
349 fstrcpy(driver->dependentfiles[i], new_name);
355 /****************************************************************************
356 ****************************************************************************/
357 static void clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
362 /****************************************************************************
363 ****************************************************************************/
364 void clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level)
369 NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
370 driver=driver_abstract.info_3;
371 clean_up_driver_struct_level_3(driver);
376 NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver;
377 driver=driver_abstract.info_6;
378 clean_up_driver_struct_level_6(driver);
384 /****************************************************************************
385 ****************************************************************************/
386 BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level, struct current_user *user)
388 NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
389 fstring architecture;
395 connection_struct *conn;
398 struct smb_passwd *smb_pass;
404 driver=driver_abstract.info_3;
406 get_short_archi(architecture, driver->environment);
408 /* connect to the print$ share under the same account as the user connected to the rpc pipe */
409 fstrcpy(user_name, uidtoname(user->uid));
410 DEBUG(10,("move_driver_to_download_area: uid %d -> user %s\n", (int)user->uid, user_name));
413 smb_pass = getsmbpwnam(user_name);
414 if(smb_pass == NULL) {
415 DEBUG(0,("move_driver_to_download_area: Unable to get smbpasswd entry for user %s\n",
422 /* Null password is ok - we are already an authenticated user... */
424 conn = make_connection("print$", user_name, null_pw, 0, "A:", user->vuid, &ecode);
427 DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
432 * Save who we are - we are temporarily becoming the connection user.
437 if (!become_user(conn, conn->vuid)) {
438 DEBUG(0,("move_driver_to_download_area: Can't become user %s\n", user_name ));
444 * make the directories version and version\driver_name
445 * under the architecture directory.
447 DEBUG(5,("Creating first directory\n"));
448 slprintf(new_dir, sizeof(new_dir), "%s\\%d", architecture, driver->cversion);
449 mkdir_internal(conn, inbuf, outbuf, new_dir);
451 /* move all the files, one by one,
452 * from archi\filexxx.yyy to
453 * archi\version\filexxx.yyy
455 * Note: drivers may list the same file name in several places. This
456 * causes problems on a second attempt to move the file. JRR
458 * Note: use the replace flag on rename_internals() call, otherwise it
459 * is very difficult to change previously installed drivers... the Windows
460 * GUI offers the user the choice to replace or keep exisitng driver. JRR
463 DEBUG(5,("Moving file now !\n"));
464 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->driverpath);
465 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->driverpath);
466 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
467 DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
468 old_name, new_name ));
469 close_cnum(conn, user->vuid);
474 if (!strequal(driver->datafile, driver->driverpath)) {
475 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->datafile);
476 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->datafile);
477 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
478 DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
479 old_name, new_name ));
480 close_cnum(conn, user->vuid);
486 if (!strequal(driver->configfile, driver->driverpath) &&
487 !strequal(driver->configfile, driver->datafile)) {
488 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->configfile);
489 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->configfile);
490 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
491 DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
492 old_name, new_name ));
493 close_cnum(conn, user->vuid);
499 if (!strequal(driver->helpfile, driver->driverpath) &&
500 !strequal(driver->helpfile, driver->datafile) &&
501 !strequal(driver->helpfile, driver->configfile)) {
502 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->helpfile);
503 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->helpfile);
504 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
505 DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
506 old_name, new_name ));
507 close_cnum(conn, user->vuid);
513 if (driver->dependentfiles) {
514 for (i=0; *driver->dependentfiles[i]; i++) {
515 if (!strequal(driver->dependentfiles[i], driver->driverpath) &&
516 !strequal(driver->dependentfiles[i], driver->datafile) &&
517 !strequal(driver->dependentfiles[i], driver->configfile) &&
518 !strequal(driver->dependentfiles[i], driver->helpfile)) {
520 for (j=0; j < i; j++) {
521 if (strequal(driver->dependentfiles[i], driver->dependentfiles[j])) {
526 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->dependentfiles[i]);
527 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->dependentfiles[i]);
528 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
529 DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
530 old_name, new_name ));
531 close_cnum(conn, user->vuid);
540 close_cnum(conn, user->vuid);
546 /****************************************************************************
547 ****************************************************************************/
548 static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
551 fstring architecture;
559 get_short_archi(architecture, driver->environment);
561 /* The names are relative. We store them in the form: \print$\arch\version\driver.xxx
562 * \\server is added in the rpc server layer.
563 * It does make sense to NOT store the server's name in the printer TDB.
566 slprintf(directory, sizeof(directory), "\\print$\\%s\\%d\\", architecture, driver->cversion);
569 fstrcpy(temp_name, driver->driverpath);
570 slprintf(driver->driverpath, sizeof(driver->driverpath), "%s%s", directory, temp_name);
572 fstrcpy(temp_name, driver->datafile);
573 slprintf(driver->datafile, sizeof(driver->datafile), "%s%s", directory, temp_name);
575 fstrcpy(temp_name, driver->configfile);
576 slprintf(driver->configfile, sizeof(driver->configfile), "%s%s", directory, temp_name);
578 fstrcpy(temp_name, driver->helpfile);
579 slprintf(driver->helpfile, sizeof(driver->helpfile), "%s%s", directory, temp_name);
581 if (driver->dependentfiles) {
582 for (i=0; *driver->dependentfiles[i]; i++) {
583 fstrcpy(temp_name, driver->dependentfiles[i]);
584 slprintf(driver->dependentfiles[i], sizeof(driver->dependentfiles[i]), "%s%s", directory, temp_name);
588 slprintf(key, sizeof(key), "%s%s/%d/%s", DRIVERS_PREFIX, architecture, driver->cversion, driver->name);
595 len += tdb_pack(buf+len, buflen-len, "dffffffff",
604 driver->defaultdatatype);
606 if (driver->dependentfiles) {
607 for (i=0; *driver->dependentfiles[i]; i++) {
608 len += tdb_pack(buf+len, buflen-len, "f",
609 driver->dependentfiles[i]);
614 buf = (char *)Realloc(buf, len);
621 kbuf.dsize = strlen(key)+1;
625 ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
631 /****************************************************************************
632 ****************************************************************************/
633 static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
635 NT_PRINTER_DRIVER_INFO_LEVEL_3 info3;
638 info3.cversion = driver->version;
639 fstrcpy(info3.environment,driver->environment);
640 fstrcpy(info3.driverpath,driver->driverpath);
641 fstrcpy(info3.datafile,driver->datafile);
642 fstrcpy(info3.configfile,driver->configfile);
643 fstrcpy(info3.helpfile,driver->helpfile);
644 fstrcpy(info3.monitorname,driver->monitorname);
645 fstrcpy(info3.defaultdatatype,driver->defaultdatatype);
646 info3.dependentfiles = driver->dependentfiles;
648 return add_a_printer_driver_3(&info3);
652 /****************************************************************************
653 ****************************************************************************/
654 static uint32 get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
656 NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
660 fstrcpy(info.name, in_prt);
661 fstrcpy(info.defaultdatatype, "RAW");
663 fstrcpy(info.driverpath, "");
664 fstrcpy(info.datafile, "");
665 fstrcpy(info.configfile, "");
666 fstrcpy(info.helpfile, "");
668 if ((info.dependentfiles=(fstring *)malloc(2*sizeof(fstring))) == NULL)
669 return ERROR_NOT_ENOUGH_MEMORY;
671 memset(info.dependentfiles, '\0', 2*sizeof(fstring));
672 fstrcpy(info.dependentfiles[0], "");
674 *info_ptr = memdup(&info, sizeof(info));
679 /****************************************************************************
680 ****************************************************************************/
681 static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch, uint32 version)
683 NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
685 fstring architecture;
692 get_short_archi(architecture, in_arch);
694 DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, in_prt));
696 slprintf(key, sizeof(key), "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, in_prt);
699 kbuf.dsize = strlen(key)+1;
701 dbuf = tdb_fetch(tdb, kbuf);
703 if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
705 if (!dbuf.dptr) return 5;
707 len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff",
716 driver.defaultdatatype);
719 while (len < dbuf.dsize) {
720 driver.dependentfiles = (fstring *)Realloc(driver.dependentfiles,
721 sizeof(fstring)*(i+2));
722 if (driver.dependentfiles == NULL)
725 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f",
726 &driver.dependentfiles[i]);
729 if (driver.dependentfiles != NULL)
730 fstrcpy(driver.dependentfiles[i], "");
732 safe_free(dbuf.dptr);
734 if (len != dbuf.dsize) {
735 if (driver.dependentfiles != NULL)
736 safe_free(driver.dependentfiles);
738 return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
741 *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
746 /****************************************************************************
747 ****************************************************************************/
748 uint32 get_a_printer_driver_9x_compatible(pstring line, fstring model)
750 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
756 slprintf(key, sizeof(key), "%s%s/%d/%s", DRIVERS_PREFIX, "WIN40", 0, model);
757 DEBUG(10,("driver key: [%s]\n", key));
760 kbuf.dsize = strlen(key)+1;
761 if (!tdb_exists(tdb, kbuf)) return False;
764 get_a_printer_driver_3(&info3, model, "Windows 4.0", 0);
766 DEBUGADD(10,("info3->name [%s]\n", info3->name));
767 DEBUGADD(10,("info3->datafile [%s]\n", info3->datafile));
768 DEBUGADD(10,("info3->helpfile [%s]\n", info3->helpfile));
769 DEBUGADD(10,("info3->monitorname [%s]\n", info3->monitorname));
770 DEBUGADD(10,("info3->defaultdatatype [%s]\n", info3->defaultdatatype));
771 for (i=0; info3->dependentfiles && *info3->dependentfiles[i]; i++) {
772 DEBUGADD(10,("info3->dependentfiles [%s]\n", info3->dependentfiles[i]));
774 DEBUGADD(10,("info3->environment [%s]\n", info3->environment));
775 DEBUGADD(10,("info3->driverpath [%s]\n", info3->driverpath));
776 DEBUGADD(10,("info3->configfile [%s]\n", info3->configfile));
778 /*pstrcat(line, info3->name); pstrcat(line, ":");*/
779 trim_string(info3->configfile, "\\print$\\WIN40\\0\\", 0);
780 pstrcat(line, info3->configfile);
782 trim_string(info3->datafile, "\\print$\\WIN40\\0\\", 0);
783 pstrcat(line, info3->datafile);
785 trim_string(info3->helpfile, "\\print$\\WIN40\\0\\", 0);
786 pstrcat(line, info3->helpfile);
788 trim_string(info3->monitorname, "\\print$\\WIN40\\0\\", 0);
789 pstrcat(line, info3->monitorname);
791 pstrcat(line, "RAW"); /*info3->defaultdatatype);*/
794 for (i=0; info3->dependentfiles &&
795 *info3->dependentfiles[i]; i++) {
796 if (i) pstrcat(line, ","); /* don't end in a "," */
797 trim_string(info3->dependentfiles[i], "\\print$\\WIN40\\0\\", 0);
798 pstrcat(line, info3->dependentfiles[i]);
806 /****************************************************************************
807 debugging function, dump at level 6 the struct in the logs
808 ****************************************************************************/
809 static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
812 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
815 DEBUG(106,("Dumping printer driver at level [%d]\n", level));
821 if (driver.info_3 == NULL)
826 DEBUGADD(106,("version:[%d]\n", info3->cversion));
827 DEBUGADD(106,("name:[%s]\n", info3->name));
828 DEBUGADD(106,("environment:[%s]\n", info3->environment));
829 DEBUGADD(106,("driverpath:[%s]\n", info3->driverpath));
830 DEBUGADD(106,("datafile:[%s]\n", info3->datafile));
831 DEBUGADD(106,("configfile:[%s]\n", info3->configfile));
832 DEBUGADD(106,("helpfile:[%s]\n", info3->helpfile));
833 DEBUGADD(106,("monitorname:[%s]\n", info3->monitorname));
834 DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
836 for (i=0; info3->dependentfiles &&
837 *info3->dependentfiles[i]; i++) {
838 DEBUGADD(106,("dependentfile:[%s]\n",
839 info3->dependentfiles[i]));
846 DEBUGADD(1,("Level not implemented\n"));
854 /****************************************************************************
855 ****************************************************************************/
856 static int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
860 len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
862 if (!nt_devmode) return len;
864 len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
865 nt_devmode->devicename,
866 nt_devmode->formname,
868 nt_devmode->specversion,
869 nt_devmode->driverversion,
871 nt_devmode->driverextra,
872 nt_devmode->orientation,
873 nt_devmode->papersize,
874 nt_devmode->paperlength,
875 nt_devmode->paperwidth,
878 nt_devmode->defaultsource,
879 nt_devmode->printquality,
882 nt_devmode->yresolution,
883 nt_devmode->ttoption,
885 nt_devmode->logpixels,
888 nt_devmode->bitsperpel,
889 nt_devmode->pelswidth,
890 nt_devmode->pelsheight,
891 nt_devmode->displayflags,
892 nt_devmode->displayfrequency,
893 nt_devmode->icmmethod,
894 nt_devmode->icmintent,
895 nt_devmode->mediatype,
896 nt_devmode->dithertype,
897 nt_devmode->reserved1,
898 nt_devmode->reserved2,
899 nt_devmode->panningwidth,
900 nt_devmode->panningheight,
901 nt_devmode->private);
904 if (nt_devmode->private) {
905 len += tdb_pack(buf+len, buflen-len, "B",
906 nt_devmode->driverextra,
907 nt_devmode->private);
910 DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname));
915 /****************************************************************************
916 ****************************************************************************/
917 static int pack_specifics(NT_PRINTER_PARAM *param, char *buf, int buflen)
921 while (param != NULL) {
922 len += tdb_pack(buf+len, buflen-len, "pfdB",
931 len += tdb_pack(buf+len, buflen-len, "p", param);
937 /****************************************************************************
938 delete a printer - this just deletes the printer info file, any open
939 handles are not affected
940 ****************************************************************************/
941 uint32 del_a_printer(char *sharename)
946 slprintf(key, sizeof(key), "%s%s",
947 PRINTERS_PREFIX, sharename);
950 kbuf.dsize=strlen(key)+1;
952 tdb_delete(tdb, kbuf);
956 /****************************************************************************
957 ****************************************************************************/
958 static uint32 add_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
962 int buflen, len, ret;
965 time_t time_unix = time(NULL);
968 * in addprinter: no servername and the printer is the name
969 * in setprinter: servername is \\server
970 * and printer is \\server\\printer
972 * Samba manages only local printers.
973 * we currently don't support things like path=\\other_server\printer
976 if (info->servername[0]!='\0') {
977 trim_string(info->printername, info->servername, NULL);
978 trim_string(info->printername, "\\", NULL);
979 info->servername[0]='\0';
983 * JFM: one day I'll forget.
984 * below that's info->portname because that's the SAMBA sharename
985 * and I made NT 'thinks' it's the portname
986 * the info->sharename is the thing you can name when you add a printer
987 * that's the short-name when you create shared printer for 95/98
988 * So I've made a limitation in SAMBA: you can only have 1 printer model
989 * behind a SAMBA share.
992 unix_to_nt_time(&time_nt, time_unix);
993 info->changeid=time_nt.low;
994 info->c_setprinter++;
1001 len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffPfffff",
1004 info->default_priority,
1021 info->printprocessor,
1025 len += pack_devicemode(info->devmode, buf+len, buflen-len);
1026 len += pack_specifics(info->specific, buf+len, buflen-len);
1028 if (buflen != len) {
1029 buf = (char *)Realloc(buf, len);
1035 slprintf(key, sizeof(key), "%s%s",
1036 PRINTERS_PREFIX, info->sharename);
1039 kbuf.dsize = strlen(key)+1;
1043 ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
1046 DEBUG(8, ("error updating printer to tdb on disk\n"));
1050 DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n",
1051 info->sharename, info->drivername, info->portname, len));
1057 /****************************************************************************
1058 ****************************************************************************/
1059 BOOL add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
1061 NT_PRINTER_PARAM *current;
1063 DEBUG(108,("add_a_specific_param\n"));
1067 if (info_2->specific == NULL)
1069 info_2->specific=param;
1073 current=info_2->specific;
1074 while (current->next != NULL) {
1075 current=current->next;
1077 current->next=param;
1082 /****************************************************************************
1083 ****************************************************************************/
1084 BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
1086 NT_PRINTER_PARAM *current;
1087 NT_PRINTER_PARAM *previous;
1089 current=info_2->specific;
1092 if (current==NULL) return (False);
1094 if ( !strcmp(current->value, param->value) &&
1095 (strlen(current->value)==strlen(param->value)) ) {
1096 DEBUG(109,("deleting first value\n"));
1097 info_2->specific=current->next;
1098 safe_free(current->data);
1100 DEBUG(109,("deleted first value\n"));
1104 current=previous->next;
1106 while ( current!=NULL ) {
1107 if (!strcmp(current->value, param->value) &&
1108 strlen(current->value)==strlen(param->value) ) {
1109 DEBUG(109,("deleting current value\n"));
1110 previous->next=current->next;
1111 safe_free(current->data);
1113 DEBUG(109,("deleted current value\n"));
1117 previous=previous->next;
1118 current=current->next;
1123 /****************************************************************************
1124 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
1125 ****************************************************************************/
1126 static void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr)
1128 NT_PRINTER_PARAM *param = *param_ptr;
1133 DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param->value));
1136 safe_free(param->data);
1142 /****************************************************************************
1143 Malloc and return an NT devicemode.
1144 ****************************************************************************/
1146 NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
1149 * should I init this ones ???
1150 nt_devmode->devicename
1154 NT_DEVICEMODE *nt_devmode = (NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE));
1156 if (nt_devmode == NULL) {
1157 DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
1161 ZERO_STRUCTP(nt_devmode);
1163 snprintf(adevice, sizeof(adevice), "\\\\%s\\%s", global_myname, default_devicename);
1164 fstrcpy(nt_devmode->devicename, adevice);
1167 fstrcpy(nt_devmode->formname, "Letter");
1169 nt_devmode->specversion = 0x0401;
1170 nt_devmode->driverversion = 0x0400;
1171 nt_devmode->size = 0x00DC;
1172 nt_devmode->driverextra = 0x0000;
1173 nt_devmode->fields = FORMNAME | TTOPTION | PRINTQUALITY |
1174 DEFAULTSOURCE | COPIES | SCALE |
1175 PAPERSIZE | ORIENTATION;
1176 nt_devmode->orientation = 1;
1177 nt_devmode->papersize = PAPER_LETTER;
1178 nt_devmode->paperlength = 0;
1179 nt_devmode->paperwidth = 0;
1180 nt_devmode->scale = 0x64;
1181 nt_devmode->copies = 01;
1182 nt_devmode->defaultsource = BIN_FORMSOURCE;
1183 nt_devmode->printquality = 0x0258;
1184 nt_devmode->color = COLOR_MONOCHROME;
1185 nt_devmode->duplex = DUP_SIMPLEX;
1186 nt_devmode->yresolution = 0;
1187 nt_devmode->ttoption = TT_SUBDEV;
1188 nt_devmode->collate = COLLATE_FALSE;
1189 nt_devmode->icmmethod = 0;
1190 nt_devmode->icmintent = 0;
1191 nt_devmode->mediatype = 0;
1192 nt_devmode->dithertype = 0;
1194 /* non utilisés par un driver d'imprimante */
1195 nt_devmode->logpixels = 0;
1196 nt_devmode->bitsperpel = 0;
1197 nt_devmode->pelswidth = 0;
1198 nt_devmode->pelsheight = 0;
1199 nt_devmode->displayflags = 0;
1200 nt_devmode->displayfrequency = 0;
1201 nt_devmode->reserved1 = 0;
1202 nt_devmode->reserved2 = 0;
1203 nt_devmode->panningwidth = 0;
1204 nt_devmode->panningheight = 0;
1206 nt_devmode->private=NULL;
1211 /****************************************************************************
1212 Deepcopy an NT devicemode.
1213 ****************************************************************************/
1215 NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
1217 NT_DEVICEMODE *new_nt_devicemode = NULL;
1219 if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
1220 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
1224 new_nt_devicemode->private = NULL;
1225 if (nt_devicemode->private != NULL) {
1226 if ((new_nt_devicemode->private = memdup(nt_devicemode->private, nt_devicemode->driverextra)) == NULL) {
1227 safe_free(new_nt_devicemode);
1228 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
1233 return new_nt_devicemode;
1236 /****************************************************************************
1237 Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
1238 ****************************************************************************/
1240 void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
1242 NT_DEVICEMODE *nt_devmode = *devmode_ptr;
1244 if(nt_devmode == NULL)
1247 DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
1249 if(nt_devmode->private)
1250 safe_free(nt_devmode->private);
1252 safe_free(nt_devmode);
1253 *devmode_ptr = NULL;
1256 /****************************************************************************
1257 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
1258 ****************************************************************************/
1259 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
1261 NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
1262 NT_PRINTER_PARAM *param_ptr;
1267 DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
1269 free_nt_devicemode(&info->devmode);
1270 free_sec_desc_buf(&info->secdesc_buf);
1272 for(param_ptr = info->specific; param_ptr; ) {
1273 NT_PRINTER_PARAM *tofree = param_ptr;
1275 param_ptr = param_ptr->next;
1276 free_nt_printer_param(&tofree);
1279 safe_free(*info_ptr);
1284 /****************************************************************************
1285 ****************************************************************************/
1286 static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
1290 NT_DEVICEMODE devmode;
1292 ZERO_STRUCT(devmode);
1294 len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
1296 if (!*nt_devmode) return len;
1298 len += tdb_unpack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
1302 &devmode.specversion,
1303 &devmode.driverversion,
1305 &devmode.driverextra,
1306 &devmode.orientation,
1308 &devmode.paperlength,
1309 &devmode.paperwidth,
1312 &devmode.defaultsource,
1313 &devmode.printquality,
1316 &devmode.yresolution,
1322 &devmode.bitsperpel,
1324 &devmode.pelsheight,
1325 &devmode.displayflags,
1326 &devmode.displayfrequency,
1330 &devmode.dithertype,
1333 &devmode.panningwidth,
1334 &devmode.panningheight,
1337 if (devmode.private) {
1338 /* the len in tdb_unpack is an int value and
1339 * devmoce.driverextra is only a short
1341 len += tdb_unpack(buf+len, buflen-len, "B", &extra_len, &devmode.private);
1342 devmode.driverextra=(uint16)extra_len;
1345 *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
1347 DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode.devicename, devmode.formname));
1348 if (devmode.private)
1349 DEBUG(8,("with a private section of %d bytes\n", devmode.driverextra));
1354 /****************************************************************************
1355 ****************************************************************************/
1356 static int unpack_specifics(NT_PRINTER_PARAM **list, char *buf, int buflen)
1359 NT_PRINTER_PARAM param, *p;
1364 len += tdb_unpack(buf+len, buflen-len, "p", &p);
1367 len += tdb_unpack(buf+len, buflen-len, "fdB",
1373 *list = memdup(¶m, sizeof(param));
1375 DEBUG(8,("specific: [%s], len: %d\n", param.value, param.data_len));
1382 /****************************************************************************
1383 get a default printer info 2 struct
1384 ****************************************************************************/
1385 static uint32 get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
1387 extern pstring global_myname;
1389 NT_PRINTER_INFO_LEVEL_2 info;
1393 snum = lp_servicenumber(sharename);
1395 fstrcpy(info.servername, global_myname);
1396 fstrcpy(info.printername, sharename);
1397 fstrcpy(info.portname, SAMBA_PRINTER_PORT_NAME);
1398 fstrcpy(info.drivername, lp_printerdriver(snum));
1399 pstrcpy(info.comment, "");
1400 fstrcpy(info.printprocessor, "winprint");
1401 fstrcpy(info.datatype, "RAW");
1403 info.attributes = PRINTER_ATTRIBUTE_SHARED \
1404 | PRINTER_ATTRIBUTE_LOCAL \
1405 | PRINTER_ATTRIBUTE_RAW_ONLY ; /* attributes */
1407 info.starttime = 0; /* Minutes since 12:00am GMT */
1408 info.untiltime = 0; /* Minutes since 12:00am GMT */
1410 info.default_priority = 1;
1412 if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
1415 if (!nt_printing_getsec(sharename, &info.secdesc_buf))
1418 *info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
1420 DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
1429 free_nt_devicemode(&info.devmode);
1430 if (info.secdesc_buf)
1431 free_sec_desc_buf(&info.secdesc_buf);
1435 /****************************************************************************
1436 ****************************************************************************/
1437 static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
1440 NT_PRINTER_INFO_LEVEL_2 info;
1442 TDB_DATA kbuf, dbuf;
1446 slprintf(key, sizeof(key), "%s%s", PRINTERS_PREFIX, sharename);
1449 kbuf.dsize = strlen(key)+1;
1451 dbuf = tdb_fetch(tdb, kbuf);
1454 return get_a_printer_2_default(info_ptr, sharename);
1456 if (!dbuf.dptr) return 1;
1459 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff",
1462 &info.default_priority,
1479 info.printprocessor,
1483 /* Samba has to have shared raw drivers. */
1484 info.attributes |= (PRINTER_ATTRIBUTE_SHARED|PRINTER_ATTRIBUTE_RAW_ONLY);
1486 len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
1487 len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
1490 nt_printing_getsec(sharename, &info.secdesc_buf);
1491 #endif /* JRATEST */
1493 safe_free(dbuf.dptr);
1494 *info_ptr=memdup(&info, sizeof(info));
1496 DEBUG(9,("Unpacked printer [%s] running driver [%s]\n",
1497 sharename, info.drivername));
1503 /****************************************************************************
1504 debugging function, dump at level 6 the struct in the logs
1505 ****************************************************************************/
1506 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1509 NT_PRINTER_INFO_LEVEL_2 *info2;
1511 DEBUG(106,("Dumping printer at level [%d]\n", level));
1517 if (printer.info_2 == NULL)
1521 info2=printer.info_2;
1523 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
1524 DEBUGADD(106,("priority:[%d]\n", info2->priority));
1525 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
1526 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
1527 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
1528 DEBUGADD(106,("status:[%d]\n", info2->status));
1529 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
1530 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
1531 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
1532 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
1533 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
1535 DEBUGADD(106,("servername:[%s]\n", info2->servername));
1536 DEBUGADD(106,("printername:[%s]\n", info2->printername));
1537 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
1538 DEBUGADD(106,("portname:[%s]\n", info2->portname));
1539 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
1540 DEBUGADD(106,("comment:[%s]\n", info2->comment));
1541 DEBUGADD(106,("location:[%s]\n", info2->location));
1542 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
1543 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
1544 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
1545 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
1551 DEBUGADD(1,("Level not implemented\n"));
1559 /****************************************************************************
1560 Get the parameters we can substitute in an NT print job.
1561 ****************************************************************************/
1563 void get_printer_subst_params(int snum, fstring *printername, fstring *sharename, fstring *portname)
1565 NT_PRINTER_INFO_LEVEL *printer = NULL;
1567 **printername = **sharename = **portname = '\0';
1569 if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
1572 fstrcpy(*printername, printer->info_2->printername);
1573 fstrcpy(*sharename, printer->info_2->sharename);
1574 fstrcpy(*portname, printer->info_2->portname);
1576 free_a_printer(&printer, 2);
1580 * The function below are the high level ones.
1581 * only those ones must be called from the spoolss code.
1585 /****************************************************************************
1586 ****************************************************************************/
1587 uint32 add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1591 dump_a_printer(printer, level);
1597 success=add_a_printer_2(printer.info_2);
1608 /****************************************************************************
1609 Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
1610 ****************************************************************************/
1612 uint32 get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename)
1615 NT_PRINTER_INFO_LEVEL *printer = NULL;
1619 DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
1625 if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
1626 DEBUG(0,("get_a_printer: malloc fail.\n"));
1629 ZERO_STRUCTP(printer);
1630 success=get_a_printer_2(&printer->info_2, sharename);
1632 dump_a_printer(*printer, level);
1633 *pp_printer = printer;
1644 DEBUG(10,("get_a_printer: [%s] level %u returning %u\n", sharename, (unsigned int)level, (unsigned int)success));
1649 /****************************************************************************
1650 Deletes a NT_PRINTER_INFO_LEVEL struct.
1651 ****************************************************************************/
1653 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
1656 NT_PRINTER_INFO_LEVEL *printer = *pp_printer;
1658 DEBUG(104,("freeing a printer at level [%d]\n", level));
1660 if (printer == NULL)
1667 if (printer->info_2 != NULL)
1669 free_nt_printer_info_level_2(&printer->info_2);
1688 /****************************************************************************
1689 ****************************************************************************/
1690 uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1693 DEBUG(104,("adding a printer at level [%d]\n", level));
1694 dump_a_printer_driver(driver, level);
1700 success=add_a_printer_driver_3(driver.info_3);
1706 success=add_a_printer_driver_6(driver.info_6);
1716 /****************************************************************************
1717 ****************************************************************************/
1718 uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
1719 fstring printername, fstring architecture, uint32 version)
1727 success=get_a_printer_driver_3(&(driver->info_3),
1729 architecture, version);
1737 if (success == 0) dump_a_printer_driver(*driver, level);
1741 /****************************************************************************
1742 ****************************************************************************/
1743 uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1751 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1752 if (driver.info_3 != NULL)
1754 info3=driver.info_3;
1755 safe_free(info3->dependentfiles);
1756 ZERO_STRUCTP(info3);
1768 NT_PRINTER_DRIVER_INFO_LEVEL_6 *info6;
1769 if (driver.info_6 != NULL)
1771 info6=driver.info_6;
1772 safe_free(info6->dependentfiles);
1773 safe_free(info6->previousnames);
1774 ZERO_STRUCTP(info6);
1791 /****************************************************************************
1792 ****************************************************************************/
1793 BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
1794 fstring value, uint8 **data, uint32 *type, uint32 *len)
1796 /* right now that's enough ! */
1797 NT_PRINTER_PARAM *param;
1800 param=printer.info_2->specific;
1802 while (param != NULL && i < param_index) {
1810 /* exited because it exist */
1812 StrnCpy(value, param->value, sizeof(fstring)-1);
1813 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
1816 ZERO_STRUCTP(*data);
1817 memcpy(*data, param->data, param->data_len);
1818 *len=param->data_len;
1822 /****************************************************************************
1823 ****************************************************************************/
1824 BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level,
1825 fstring value, uint8 **data, uint32 *type, uint32 *len)
1827 /* right now that's enough ! */
1828 NT_PRINTER_PARAM *param;
1830 DEBUG(105, ("get_specific_param\n"));
1832 param=printer.info_2->specific;
1834 while (param != NULL)
1836 if ( !strcmp(value, param->value)
1837 && strlen(value)==strlen(param->value))
1843 DEBUG(106, ("found one param\n"));
1846 /* exited because it exist */
1849 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
1852 memcpy(*data, param->data, param->data_len);
1853 *len=param->data_len;
1855 DEBUG(106, ("exit of get_specific_param:true\n"));
1858 DEBUG(106, ("exit of get_specific_param:false\n"));
1862 /****************************************************************************
1863 Store a security desc for a printer.
1864 ****************************************************************************/
1866 uint32 nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
1868 SEC_DESC_BUF *new_secdesc_ctr = NULL;
1869 SEC_DESC_BUF *old_secdesc_ctr = NULL;
1871 TALLOC_CTX *mem_ctx = NULL;
1875 mem_ctx = talloc_init();
1876 if (mem_ctx == NULL)
1879 /* The old owner and group sids of the security descriptor are not
1880 present when new ACEs are added or removed by changing printer
1881 permissions through NT. If they are NULL in the new security
1882 descriptor then copy them over from the old one. */
1884 if (!secdesc_ctr->sec->owner_sid || !secdesc_ctr->sec->grp_sid) {
1885 DOM_SID *owner_sid, *group_sid;
1886 SEC_DESC *psd = NULL;
1889 nt_printing_getsec(printername, &old_secdesc_ctr);
1891 /* Pick out correct owner and group sids */
1893 owner_sid = secdesc_ctr->sec->owner_sid ?
1894 secdesc_ctr->sec->owner_sid :
1895 old_secdesc_ctr->sec->owner_sid;
1897 group_sid = secdesc_ctr->sec->grp_sid ?
1898 secdesc_ctr->sec->grp_sid :
1899 old_secdesc_ctr->sec->grp_sid;
1901 /* Make a deep copy of the security descriptor */
1903 psd = make_sec_desc(secdesc_ctr->sec->revision,
1904 secdesc_ctr->sec->type,
1905 owner_sid, group_sid,
1906 secdesc_ctr->sec->sacl,
1907 secdesc_ctr->sec->dacl,
1910 new_secdesc_ctr = make_sec_desc_buf(size, psd);
1912 /* Free up memory */
1914 free_sec_desc(&psd);
1915 free_sec_desc_buf(&old_secdesc_ctr);
1918 if (!new_secdesc_ctr) {
1919 new_secdesc_ctr = secdesc_ctr;
1922 /* Store the security descriptor in a tdb */
1924 prs_init(&ps, (uint32)sec_desc_size(new_secdesc_ctr->sec) +
1925 sizeof(SEC_DESC_BUF), 4, mem_ctx, MARSHALL);
1927 if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr,
1929 status = ERROR_INVALID_FUNCTION;
1933 slprintf(key, sizeof(key), "SECDESC/%s", printername);
1935 if (tdb_prs_store(tdb, key, &ps)==0) {
1938 DEBUG(1,("Failed to store secdesc for %s\n", printername));
1939 status = ERROR_INVALID_FUNCTION;
1942 /* Free mallocated memory */
1945 free_sec_desc_buf(&old_secdesc_ctr);
1947 if (new_secdesc_ctr != secdesc_ctr) {
1948 free_sec_desc_buf(&new_secdesc_ctr);
1953 talloc_destroy(mem_ctx);
1957 /****************************************************************************
1958 Construct a default security descriptor buffer for a printer.
1959 ****************************************************************************/
1961 static SEC_DESC_BUF *construct_default_printer_sdb(void)
1965 SEC_ACL *psa = NULL;
1966 SEC_DESC_BUF *sdb = NULL;
1967 SEC_DESC *psd = NULL;
1972 /* Create an ACE where Everyone is allowed to print */
1974 init_sec_access(&sa, PRINTER_ACE_PRINT);
1975 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
1976 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
1979 /* Make the security descriptor owned by the Administrators group
1980 on the PDC of the domain. */
1982 if (winbind_lookup_name(lp_workgroup(), &owner_sid, &name_type)) {
1983 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
1986 /* Backup plan - make printer owned by admins or root. This should
1987 emulate a lanman printer as security settings can't be
1990 if (!lookup_name( "Printer Administrators", &owner_sid, &name_type) &&
1991 !lookup_name( "Administrators", &owner_sid, &name_type) &&
1992 !lookup_name( "Administrator", &owner_sid, &name_type) &&
1993 !lookup_name("root", &owner_sid, &name_type)) {
1994 sid_copy(&owner_sid, &global_sid_World);
1998 init_sec_access(&sa, PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT);
1999 init_sec_ace(&ace[1], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
2000 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
2002 /* The ACL revision number in rpc_secdesc.h differs from the one
2003 created by NT when setting ACE entries in printer
2004 descriptors. NT4 complains about the property being edited by a
2007 #define NT4_ACL_REVISION 0x2
2009 if ((psa = make_sec_acl(NT4_ACL_REVISION, 2, ace)) != NULL) {
2010 psd = make_sec_desc(SEC_DESC_REVISION,
2011 SEC_DESC_SELF_RELATIVE |
2012 SEC_DESC_DACL_PRESENT,
2014 NULL, psa, &sd_size);
2019 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
2023 sdb = make_sec_desc_buf(sd_size, psd);
2025 DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
2026 (unsigned int)sd_size));
2028 free_sec_desc(&psd);
2032 /****************************************************************************
2033 Get a security desc for a printer.
2034 ****************************************************************************/
2036 BOOL nt_printing_getsec(char *printername, SEC_DESC_BUF **secdesc_ctr)
2039 TALLOC_CTX *mem_ctx = NULL;
2042 mem_ctx = talloc_init();
2043 if (mem_ctx == NULL)
2046 /* Fetch security descriptor from tdb */
2048 slprintf(key, sizeof(key), "SECDESC/%s", printername);
2050 if (tdb_prs_fetch(tdb, key, &ps, mem_ctx)!=0 ||
2051 !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
2053 DEBUG(4,("using default secdesc for %s\n", printername));
2055 if (!(*secdesc_ctr = construct_default_printer_sdb())) {
2056 talloc_destroy(mem_ctx);
2060 talloc_destroy(mem_ctx);
2064 /* If security descriptor is owned by S-1-1-0 and winbindd is up,
2065 this security descriptor has been created when winbindd was
2066 down. Take ownership of security descriptor. */
2068 if (sid_equal((*secdesc_ctr)->sec->owner_sid, &global_sid_World)) {
2072 /* Change sd owner to workgroup administrator */
2074 if (winbind_lookup_name(lp_workgroup(), &owner_sid,
2076 SEC_DESC_BUF *new_secdesc_ctr = NULL;
2077 SEC_DESC *psd = NULL;
2082 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
2084 psd = make_sec_desc((*secdesc_ctr)->sec->revision,
2085 (*secdesc_ctr)->sec->type,
2087 (*secdesc_ctr)->sec->grp_sid,
2088 (*secdesc_ctr)->sec->sacl,
2089 (*secdesc_ctr)->sec->dacl,
2092 new_secdesc_ctr = make_sec_desc_buf(size, psd);
2094 free_sec_desc(&psd);
2096 /* Swap with other one */
2098 free_sec_desc_buf(secdesc_ctr);
2099 *secdesc_ctr = new_secdesc_ctr;
2103 nt_printing_setsec(printername, *secdesc_ctr);
2108 talloc_destroy(mem_ctx);
2114 1: level not implemented
2115 2: file doesn't exist
2116 3: can't allocate memory
2117 4: can't free memory
2118 5: non existant struct
2122 A printer and a printer driver are 2 different things.
2123 NT manages them separatelly, Samba does the same.
2124 Why ? Simply because it's easier and it makes sense !
2126 Now explanation: You have 3 printers behind your samba server,
2127 2 of them are the same make and model (laser A and B). But laser B
2128 has an 3000 sheet feeder and laser A doesn't such an option.
2129 Your third printer is an old dot-matrix model for the accounting :-).
2131 If the /usr/local/samba/lib directory (default dir), you will have
2132 5 files to describe all of this.
2134 3 files for the printers (1 by printer):
2137 NTprinter_accounting
2138 2 files for the drivers (1 for the laser and 1 for the dot matrix)
2139 NTdriver_printer model X
2140 NTdriver_printer model Y
2142 jfm: I should use this comment for the text file to explain
2143 same thing for the forms BTW.
2144 Je devrais mettre mes commentaires en francais, ca serait mieux :-)
2148 /****************************************************************************
2149 Check a user has permissions to perform the given operation
2151 if user is NULL then use the current_user structure
2152 ****************************************************************************/
2153 BOOL print_access_check(struct current_user *user, int snum,
2154 uint32 required_access)
2156 SEC_DESC_BUF *secdesc = NULL;
2157 uint32 access_granted, status;
2161 extern struct current_user current_user;
2163 if (!user) user = ¤t_user;
2165 /* always allow root or printer admins to do anything */
2167 user_in_list(uidtoname(user->uid), lp_printer_admin(snum))) {
2171 /* Get printer name */
2172 pname = PRINTERNAME(snum);
2173 if (!pname || !*pname) pname = SERVICE(snum);
2175 if (!pname || !*pname) return False;
2177 /* Get printer security descriptor */
2178 nt_printing_getsec(pname, &secdesc);
2180 /* The ACE for Full Control in a printer security descriptor
2181 doesn't seem to map properly to the access checking model. For
2182 it to work properly it should be the logical OR of all the other
2183 values, i.e PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT.
2184 This would cause the access check to simply fall out when we
2185 check against any subset of these bits. To get things to work,
2186 change every ACE mask of PRINTER_ACE_FULL_CONTROL to
2187 PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT before
2188 performing the access check. I'm sure there is a better way to
2191 /* You forgot to also change the *required access* from PRINTER_ACE_FULL_CONTROL
2192 to PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT before doing the check.
2193 This took me 3 hours to find !!!!! JRA.
2196 if (required_access & PRINTER_ACE_FULL_CONTROL) {
2197 required_access |= (PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT);
2198 required_access &= ~PRINTER_ACE_FULL_CONTROL;
2201 if (secdesc && secdesc->sec && secdesc->sec->dacl &&
2202 secdesc->sec->dacl->ace) {
2203 for(i = 0; i < secdesc->sec->dacl->num_aces; i++) {
2204 if (secdesc->sec->dacl->ace[i].info.mask ==
2205 PRINTER_ACE_FULL_CONTROL) {
2206 secdesc->sec->dacl->ace[i].info.mask =
2207 PRINTER_ACE_MANAGE_DOCUMENTS |
2215 result = se_access_check(secdesc->sec, user, required_access,
2216 &access_granted, &status);
2218 DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE"));
2220 /* Free mallocated memory */
2221 free_sec_desc_buf(&secdesc);
2226 /****************************************************************************
2227 Check the time parameters allow a print operation.
2228 *****************************************************************************/
2230 BOOL print_time_access_check(int snum)
2232 NT_PRINTER_INFO_LEVEL *printer = NULL;
2234 time_t now = time(NULL);
2238 if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
2241 if (printer->info_2->starttime == 0 && printer->info_2->untiltime == 0)
2245 mins = (uint32)t->tm_hour*60 + (uint32)t->tm_min;
2247 if (mins >= printer->info_2->starttime && mins <= printer->info_2->untiltime)
2250 free_a_printer(&printer, 2);