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 one default form to support our default printer. Msoft adds the
39 forms it wants and in the ORDER it wants them (note: DEVMODE papersize is an
40 array index). Letter is always first, so (for the current code) additions
41 always put things in the correct order. */
42 static nt_forms_struct default_forms[] = {
43 {"Letter", 0x2, 0x34b5b, 0x44367, 0x0, 0x0, 0x34b5b, 0x44367},
47 /****************************************************************************
48 open the NT printing tdb
49 ****************************************************************************/
50 BOOL nt_printing_init(void)
52 static pid_t local_pid;
53 char *vstring = "INFO/version";
55 if (tdb && local_pid == sys_getpid()) return True;
56 tdb = tdb_open(lock_path("ntdrivers.tdb"), 0, 0, O_RDWR|O_CREAT, 0600);
58 DEBUG(0,("Failed to open nt drivers database\n"));
62 local_pid = sys_getpid();
64 /* handle a Samba upgrade */
65 tdb_lock_bystring(tdb, vstring);
66 if (tdb_fetch_int(tdb, vstring) != DATABASE_VERSION) {
67 tdb_traverse(tdb, (tdb_traverse_func)tdb_delete, NULL);
68 tdb_store_int(tdb, vstring, DATABASE_VERSION);
70 tdb_unlock_bystring(tdb, vstring);
76 /****************************************************************************
77 get a form struct list
78 ****************************************************************************/
79 int get_ntforms(nt_forms_struct **list)
81 TDB_DATA kbuf, newkey, dbuf;
87 for (kbuf = tdb_firstkey(tdb);
89 newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
90 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0) continue;
92 dbuf = tdb_fetch(tdb, kbuf);
93 if (!dbuf.dptr) continue;
95 fstrcpy(form.name, kbuf.dptr+strlen(FORMS_PREFIX));
96 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddd",
97 &i, &form.flag, &form.width, &form.length, &form.left,
98 &form.top, &form.right, &form.bottom);
100 if (ret != dbuf.dsize) continue;
102 /* allocate space and populate the list in correct order */
104 *list = Realloc(*list, sizeof(nt_forms_struct)*(i+1));
110 /* we should never return a null forms list or NT gets unhappy */
112 *list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));
113 n = sizeof(default_forms) / sizeof(default_forms[0]);
120 /****************************************************************************
121 write a form struct list
122 ****************************************************************************/
123 int write_ntforms(nt_forms_struct **list, int number)
130 for (i=0;i<number;i++) {
131 /* save index, so list is rebuilt in correct order */
132 len = tdb_pack(buf, sizeof(buf), "dddddddd",
133 i, (*list)[i].flag, (*list)[i].width, (*list)[i].length,
134 (*list)[i].left, (*list)[i].top, (*list)[i].right,
136 if (len > sizeof(buf)) break;
137 slprintf(key, sizeof(key), "%s%s", FORMS_PREFIX, (*list)[i].name);
138 kbuf.dsize = strlen(key)+1;
142 if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) break;
148 /****************************************************************************
149 add a form struct at the end of the list
150 ****************************************************************************/
151 BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
158 * NT tries to add forms even when
159 * they are already in the base
160 * only update the values if already present
165 unistr2_to_ascii(form_name, &form->name, sizeof(form_name)-1);
166 for (n=0; n<*count && update==False; n++)
168 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
170 DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
177 if((*list=Realloc(*list, (n+1)*sizeof(nt_forms_struct))) == NULL)
179 unistr2_to_ascii((*list)[n].name, &form->name, sizeof((*list)[n].name)-1);
183 (*list)[n].flag=form->flags;
184 (*list)[n].width=form->size_x;
185 (*list)[n].length=form->size_y;
186 (*list)[n].left=form->left;
187 (*list)[n].top=form->top;
188 (*list)[n].right=form->right;
189 (*list)[n].bottom=form->bottom;
194 /****************************************************************************
195 delete a named form struct
196 ****************************************************************************/
197 BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, uint32 *ret)
208 * Don't delete the last form (no empty lists).
209 * CHECKME ! Is this correct ? JRA.
211 *ret = ERROR_INVALID_PARAMETER;
215 unistr2_to_ascii(form_name, del_name, sizeof(form_name)-1);
217 for (n=0; n<*count; n++) {
218 if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
219 DEBUG(103, ("delete_a_form, [%s] in list\n", form_name));
225 DEBUG(10,("delete_a_form, [%s] not found\n", form_name));
226 *ret = ERROR_INVALID_PARAMETER;
230 slprintf(key, sizeof(key), "%s%s", FORMS_PREFIX, (*list)[n].name);
231 kbuf.dsize = strlen(key)+1;
233 if (tdb_delete(tdb, kbuf) != 0) {
234 *ret = ERROR_NOT_ENOUGH_MEMORY;
241 /****************************************************************************
243 ****************************************************************************/
244 void update_a_form(nt_forms_struct **list, const FORM *form, int count)
248 unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
250 DEBUG(106, ("[%s]\n", form_name));
251 for (n=0; n<count; n++)
253 DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
254 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
258 if (n==count) return;
260 (*list)[n].flag=form->flags;
261 (*list)[n].width=form->size_x;
262 (*list)[n].length=form->size_y;
263 (*list)[n].left=form->left;
264 (*list)[n].top=form->top;
265 (*list)[n].right=form->right;
266 (*list)[n].bottom=form->bottom;
269 /****************************************************************************
270 get the nt drivers list
272 traverse the database and look-up the matching names
273 ****************************************************************************/
274 int get_ntdrivers(fstring **list, char *architecture, uint32 version)
279 TDB_DATA kbuf, newkey;
281 get_short_archi(short_archi, architecture);
282 slprintf(key, sizeof(key), "%s%s/%d/", DRIVERS_PREFIX, short_archi, version);
284 for (kbuf = tdb_firstkey(tdb);
286 newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
287 if (strncmp(kbuf.dptr, key, strlen(key)) != 0) continue;
289 if((*list = Realloc(*list, sizeof(fstring)*(total+1))) == NULL)
292 fstrcpy((*list)[total], kbuf.dptr+strlen(key));
299 /****************************************************************************
300 function to do the mapping between the long architecture name and
302 ****************************************************************************/
303 BOOL get_short_archi(char *short_archi, char *long_archi)
310 struct table archi_table[]=
312 {"Windows 4.0", "WIN40" },
313 {"Windows NT x86", "W32X86" },
314 {"Windows NT R4000", "W32MIPS" },
315 {"Windows NT Alpha_AXP", "W32ALPHA" },
316 {"Windows NT PowerPC", "W32PPC" },
322 DEBUG(107,("Getting architecture dependant directory\n"));
325 } while ( (archi_table[i].long_archi!=NULL ) &&
326 StrCaseCmp(long_archi, archi_table[i].long_archi) );
328 if (archi_table[i].long_archi==NULL) {
329 DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
333 StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
335 DEBUGADD(108,("index: [%d]\n", i));
336 DEBUGADD(108,("long architecture: [%s]\n", long_archi));
337 DEBUGADD(108,("short architecture: [%s]\n", short_archi));
342 /****************************************************************************
343 Determine the correct cVersion associated with an architecture and driver
344 ****************************************************************************/
345 static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in)
351 char buf[PE_HEADER_SIZE];
354 /* If architecture is Windows 95/98, the version is always 0. */
355 if (strcmp(architecture, "WIN40") == 0) {
356 DEBUG(10,("get_correct_cversion: Driver is Win9x, cversion = 0\n"));
360 /* Open the driver file (Portable Executable format) and determine the
361 * deriver the cversion.
363 if ((service = find_service("print$")) == -1) {
364 DEBUG(3,("get_correct_cversion: Can't find print$ service\n"));
368 slprintf(driverpath, sizeof(driverpath), "%s/%s/%s",
369 lp_pathname(service), architecture, driverpath_in);
371 dos_to_unix(driverpath, True);
373 if ((fd = sys_open(driverpath, O_RDONLY, 0)) == -1) {
374 DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
379 if ((byte_count = read(fd, buf, DOS_HEADER_SIZE)) < DOS_HEADER_SIZE) {
380 DEBUG(3,("get_correct_cversion: File [%s] DOS header too short, bytes read = %d\n",
381 driverpath, byte_count));
385 /* Is this really a DOS header? */
386 if (SVAL(buf,DOS_HEADER_MAGIC_OFFSET) != DOS_HEADER_MAGIC) {
387 DEBUG(6,("get_correct_cversion: File [%s] bad DOS magic = 0x%x\n",
388 driverpath, SVAL(buf,DOS_HEADER_MAGIC_OFFSET)));
392 /* Skip OEM header (if any) and the DOS stub to start of Windows header */
393 if (sys_lseek(fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
394 DEBUG(3,("get_correct_cversion: File [%s] too short, errno = %d\n",
399 if ((byte_count = read(fd, buf, PE_HEADER_SIZE)) < PE_HEADER_SIZE) {
400 DEBUG(3,("get_correct_cversion: File [%s] Windows header too short, bytes read = %d\n",
401 driverpath, byte_count));
406 /* The header may be a PE (Portable Executable) or an NE (New Executable) */
407 if (IVAL(buf,PE_HEADER_SIGNATURE_OFFSET) == PE_HEADER_SIGNATURE) {
408 if (SVAL(buf,PE_HEADER_MACHINE_OFFSET) == PE_HEADER_MACHINE_I386) {
410 switch (SVAL(buf,PE_HEADER_MAJOR_OS_VER_OFFSET)) {
411 case 4: cversion = 2; break; /* Win NT 4 */
412 case 5: cversion = 3; break; /* Win 2000 */
414 DEBUG(6,("get_correct_cversion: PE formated file [%s] bad version = %d\n",
415 driverpath, SVAL(buf,PE_HEADER_MAJOR_OS_VER_OFFSET)));
419 DEBUG(6,("get_correct_cversion: PE formatted file [%s] wrong machine = 0x%x\n",
420 driverpath, SVAL(buf,PE_HEADER_MACHINE_OFFSET)));
424 } else if (SVAL(buf,NE_HEADER_SIGNATURE_OFFSET) == NE_HEADER_SIGNATURE) {
425 if (CVAL(buf,NE_HEADER_TARGET_OS_OFFSET) == NE_HEADER_TARGOS_WIN ) {
427 switch (CVAL(buf,NE_HEADER_MAJOR_VER_OFFSET)) {
428 case 3: cversion = 0; break; /* Win 3.x / Win 9x / Win ME */
429 /* case ?: cversion = 1; break;*/ /* Win NT 3.51 ... needs research JRR */
431 DEBUG(6,("get_correct_cversion: NE formated file [%s] bad version = %d\n",
432 driverpath, CVAL(buf,NE_HEADER_MAJOR_VER_OFFSET)));
436 DEBUG(6,("get_correct_cversion: NE formatted file [%s] wrong target OS = 0x%x\n",
437 driverpath, CVAL(buf,NE_HEADER_TARGET_OS_OFFSET)));
442 DEBUG(6,("get_correct_cversion: Unknown file format [%s], signature = 0x%x\n",
443 driverpath, IVAL(buf,PE_HEADER_SIGNATURE_OFFSET)));
447 DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
448 driverpath, cversion));
458 /****************************************************************************
459 ****************************************************************************/
460 static uint32 clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
462 fstring architecture;
467 /* clean up the driver name.
468 * we can get .\driver.dll
469 * or worse c:\windows\system\driver.dll !
471 /* using an intermediate string to not have overlaping memcpy()'s */
472 if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
473 fstrcpy(new_name, p+1);
474 fstrcpy(driver->driverpath, new_name);
477 if ((p = strrchr(driver->datafile,'\\')) != NULL) {
478 fstrcpy(new_name, p+1);
479 fstrcpy(driver->datafile, new_name);
482 if ((p = strrchr(driver->configfile,'\\')) != NULL) {
483 fstrcpy(new_name, p+1);
484 fstrcpy(driver->configfile, new_name);
487 if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
488 fstrcpy(new_name, p+1);
489 fstrcpy(driver->helpfile, new_name);
492 if (driver->dependentfiles) {
493 for (i=0; *driver->dependentfiles[i]; i++) {
494 if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
495 fstrcpy(new_name, p+1);
496 fstrcpy(driver->dependentfiles[i], new_name);
501 get_short_archi(architecture, driver->environment);
503 /* jfm:7/16/2000 the client always sends the cversion=0.
504 * The server should check which version the driver is by reading
505 * the PE header of driver->driverpath.
507 * For Windows 95/98 the version is 0 (so the value sent is correct)
508 * For Windows NT (the architecture doesn't matter)
510 * NT 3.5/3.51: cversion=1
514 if ((driver->cversion = get_correct_cversion(architecture,
515 driver->driverpath)) == -1)
516 return ERROR_INVALID_PARAMETER; /* Not the best error. Fix JRR */
518 return NT_STATUS_NO_PROBLEMO;
521 /****************************************************************************
522 ****************************************************************************/
523 static uint32 clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
525 fstring architecture;
530 /* clean up the driver name.
531 * we can get .\driver.dll
532 * or worse c:\windows\system\driver.dll !
534 /* using an intermediate string to not have overlaping memcpy()'s */
535 if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
536 fstrcpy(new_name, p+1);
537 fstrcpy(driver->driverpath, new_name);
540 if ((p = strrchr(driver->datafile,'\\')) != NULL) {
541 fstrcpy(new_name, p+1);
542 fstrcpy(driver->datafile, new_name);
545 if ((p = strrchr(driver->configfile,'\\')) != NULL) {
546 fstrcpy(new_name, p+1);
547 fstrcpy(driver->configfile, new_name);
550 if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
551 fstrcpy(new_name, p+1);
552 fstrcpy(driver->helpfile, new_name);
555 if (driver->dependentfiles) {
556 for (i=0; *driver->dependentfiles[i]; i++) {
557 if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
558 fstrcpy(new_name, p+1);
559 fstrcpy(driver->dependentfiles[i], new_name);
564 get_short_archi(architecture, driver->environment);
566 /* jfm:7/16/2000 the client always sends the cversion=0.
567 * The server should check which version the driver is by reading
568 * the PE header of driver->driverpath.
570 * For Windows 95/98 the version is 0 (so the value sent is correct)
571 * For Windows NT (the architecture doesn't matter)
573 * NT 3.5/3.51: cversion=1
577 if ((driver->version = get_correct_cversion(architecture,
578 driver->driverpath)) == -1)
579 return ERROR_INVALID_PARAMETER; /* Not the best error. Fix JRR */
581 return NT_STATUS_NO_PROBLEMO;
584 /****************************************************************************
585 ****************************************************************************/
586 void clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level)
591 NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
592 driver=driver_abstract.info_3;
593 clean_up_driver_struct_level_3(driver);
598 NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver;
599 driver=driver_abstract.info_6;
600 clean_up_driver_struct_level_6(driver);
606 /****************************************************************************
607 This function sucks and should be replaced. JRA.
608 ****************************************************************************/
610 static void convert_level_6_to_level3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dst, NT_PRINTER_DRIVER_INFO_LEVEL_6 *src)
612 dst->cversion = src->version;
614 fstrcpy( dst->name, src->name);
615 fstrcpy( dst->environment, src->environment);
616 fstrcpy( dst->driverpath, src->driverpath);
617 fstrcpy( dst->datafile, src->datafile);
618 fstrcpy( dst->configfile, src->configfile);
619 fstrcpy( dst->helpfile, src->helpfile);
620 fstrcpy( dst->monitorname, src->monitorname);
621 fstrcpy( dst->defaultdatatype, src->defaultdatatype);
622 dst->dependentfiles = src->dependentfiles;
626 /****************************************************************************
627 ****************************************************************************/
628 BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level, struct current_user *user, uint32 *perr)
630 NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
631 NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver;
632 fstring architecture;
638 connection_struct *conn;
641 struct smb_passwd *smb_pass;
647 memset(inbuf, '\0', sizeof(inbuf));
648 memset(outbuf, '\0', sizeof(outbuf));
651 driver=driver_abstract.info_3;
653 convert_level_6_to_level3(&converted_driver, driver_abstract.info_6);
654 driver = &converted_driver;
656 DEBUG(0,("move_driver_to_download_area: Unknown info level (%u)\n", (unsigned int)level ));
660 get_short_archi(architecture, driver->environment);
663 smb_pass = getsmbpwuid(user->uid);
664 if(smb_pass == NULL) {
665 DEBUG(0,("move_driver_to_download_area: Unable to get smbpasswd entry for uid %u\n",
666 (unsigned int)user->uid ));
672 /* connect to the print$ share under the same account as the user connected to the rpc pipe */
673 fstrcpy(user_name, smb_pass->smb_name );
674 DEBUG(10,("move_driver_to_download_area: uid %d -> user %s\n", (int)user->uid, user_name));
676 /* Null password is ok - we are already an authenticated user... */
678 conn = make_connection("print$", user_name, null_pw, 0, "A:", user->vuid, &ecode);
681 DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
682 *perr = (uint32)ecode;
687 * Save who we are - we are temporarily becoming the connection user.
692 if (!become_user(conn, conn->vuid)) {
693 DEBUG(0,("move_driver_to_download_area: Can't become user %s\n", user_name ));
699 * make the directories version and version\driver_name
700 * under the architecture directory.
702 DEBUG(5,("Creating first directory\n"));
703 slprintf(new_dir, sizeof(new_dir), "%s\\%d", architecture, driver->cversion);
704 mkdir_internal(conn, inbuf, outbuf, new_dir);
706 /* move all the files, one by one,
707 * from archi\filexxx.yyy to
708 * archi\version\filexxx.yyy
710 * Note: drivers may list the same file name in several places. This
711 * causes problems on a second attempt to move the file. JRR
713 * Note: use the replace flag on rename_internals() call, otherwise it
714 * is very difficult to change previously installed drivers... the Windows
715 * GUI offers the user the choice to replace or keep exisitng driver. JRR
718 DEBUG(5,("Moving file now !\n"));
720 if (driver->driverpath && strlen(driver->driverpath)) {
721 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->driverpath);
722 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->driverpath);
723 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
724 DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
725 old_name, new_name ));
726 close_cnum(conn, user->vuid);
728 *perr = (uint32)SVAL(outbuf,smb_err);
733 if (driver->datafile && strlen(driver->datafile)) {
734 if (!strequal(driver->datafile, driver->driverpath)) {
735 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->datafile);
736 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->datafile);
737 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
738 DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
739 old_name, new_name ));
740 close_cnum(conn, user->vuid);
742 *perr = (uint32)SVAL(outbuf,smb_err);
748 if (driver->configfile && strlen(driver->configfile)) {
749 if (!strequal(driver->configfile, driver->driverpath) &&
750 !strequal(driver->configfile, driver->datafile)) {
751 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->configfile);
752 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->configfile);
753 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
754 DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
755 old_name, new_name ));
756 close_cnum(conn, user->vuid);
758 *perr = (uint32)SVAL(outbuf,smb_err);
764 if (driver->helpfile && strlen(driver->helpfile)) {
765 if (!strequal(driver->helpfile, driver->driverpath) &&
766 !strequal(driver->helpfile, driver->datafile) &&
767 !strequal(driver->helpfile, driver->configfile)) {
768 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->helpfile);
769 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->helpfile);
770 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
771 DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
772 old_name, new_name ));
773 close_cnum(conn, user->vuid);
775 *perr = (uint32)SVAL(outbuf,smb_err);
781 if (driver->dependentfiles) {
782 for (i=0; *driver->dependentfiles[i]; i++) {
783 if (!strequal(driver->dependentfiles[i], driver->driverpath) &&
784 !strequal(driver->dependentfiles[i], driver->datafile) &&
785 !strequal(driver->dependentfiles[i], driver->configfile) &&
786 !strequal(driver->dependentfiles[i], driver->helpfile)) {
788 for (j=0; j < i; j++) {
789 if (strequal(driver->dependentfiles[i], driver->dependentfiles[j])) {
794 slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->dependentfiles[i]);
795 slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->dependentfiles[i]);
796 if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
797 DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
798 old_name, new_name ));
799 close_cnum(conn, user->vuid);
801 *perr = (uint32)SVAL(outbuf,smb_err);
809 close_cnum(conn, user->vuid);
815 /****************************************************************************
816 ****************************************************************************/
817 static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
820 fstring architecture;
828 get_short_archi(architecture, driver->environment);
830 /* The names are relative. We store them in the form: \print$\arch\version\driver.xxx
831 * \\server is added in the rpc server layer.
832 * It does make sense to NOT store the server's name in the printer TDB.
835 slprintf(directory, sizeof(directory), "\\print$\\%s\\%d\\", architecture, driver->cversion);
838 fstrcpy(temp_name, driver->driverpath);
839 slprintf(driver->driverpath, sizeof(driver->driverpath), "%s%s", directory, temp_name);
841 fstrcpy(temp_name, driver->datafile);
842 slprintf(driver->datafile, sizeof(driver->datafile), "%s%s", directory, temp_name);
844 fstrcpy(temp_name, driver->configfile);
845 slprintf(driver->configfile, sizeof(driver->configfile), "%s%s", directory, temp_name);
847 fstrcpy(temp_name, driver->helpfile);
848 slprintf(driver->helpfile, sizeof(driver->helpfile), "%s%s", directory, temp_name);
850 if (driver->dependentfiles) {
851 for (i=0; *driver->dependentfiles[i]; i++) {
852 fstrcpy(temp_name, driver->dependentfiles[i]);
853 slprintf(driver->dependentfiles[i], sizeof(driver->dependentfiles[i]), "%s%s", directory, temp_name);
857 slprintf(key, sizeof(key), "%s%s/%d/%s", DRIVERS_PREFIX, architecture, driver->cversion, driver->name);
859 DEBUG(5,("add_a_printer_driver_3: Adding driver with key %s\n", key ));
866 len += tdb_pack(buf+len, buflen-len, "dffffffff",
875 driver->defaultdatatype);
877 if (driver->dependentfiles) {
878 for (i=0; *driver->dependentfiles[i]; i++) {
879 len += tdb_pack(buf+len, buflen-len, "f",
880 driver->dependentfiles[i]);
885 buf = (char *)Realloc(buf, len);
892 kbuf.dsize = strlen(key)+1;
896 ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
899 DEBUG(0,("add_a_printer_driver_3: Adding driver with key %s failed.\n", key ));
905 /****************************************************************************
906 ****************************************************************************/
907 static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
909 NT_PRINTER_DRIVER_INFO_LEVEL_3 info3;
912 info3.cversion = driver->version;
913 fstrcpy(info3.name,driver->name);
914 fstrcpy(info3.environment,driver->environment);
915 fstrcpy(info3.driverpath,driver->driverpath);
916 fstrcpy(info3.datafile,driver->datafile);
917 fstrcpy(info3.configfile,driver->configfile);
918 fstrcpy(info3.helpfile,driver->helpfile);
919 fstrcpy(info3.monitorname,driver->monitorname);
920 fstrcpy(info3.defaultdatatype,driver->defaultdatatype);
921 info3.dependentfiles = driver->dependentfiles;
923 return add_a_printer_driver_3(&info3);
927 /****************************************************************************
928 ****************************************************************************/
929 static uint32 get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
931 NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
935 fstrcpy(info.name, in_prt);
936 fstrcpy(info.defaultdatatype, "RAW");
938 fstrcpy(info.driverpath, "");
939 fstrcpy(info.datafile, "");
940 fstrcpy(info.configfile, "");
941 fstrcpy(info.helpfile, "");
943 if ((info.dependentfiles=(fstring *)malloc(2*sizeof(fstring))) == NULL)
944 return ERROR_NOT_ENOUGH_MEMORY;
946 memset(info.dependentfiles, '\0', 2*sizeof(fstring));
947 fstrcpy(info.dependentfiles[0], "");
949 *info_ptr = memdup(&info, sizeof(info));
954 /****************************************************************************
955 ****************************************************************************/
956 static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch, uint32 version)
958 NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
960 fstring architecture;
967 get_short_archi(architecture, in_arch);
969 DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, in_prt));
971 slprintf(key, sizeof(key), "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, in_prt);
974 kbuf.dsize = strlen(key)+1;
976 dbuf = tdb_fetch(tdb, kbuf);
978 if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
980 if (!dbuf.dptr) return 5;
982 len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff",
991 driver.defaultdatatype);
994 while (len < dbuf.dsize) {
995 driver.dependentfiles = (fstring *)Realloc(driver.dependentfiles,
996 sizeof(fstring)*(i+2));
997 if (driver.dependentfiles == NULL)
1000 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f",
1001 &driver.dependentfiles[i]);
1004 if (driver.dependentfiles != NULL)
1005 fstrcpy(driver.dependentfiles[i], "");
1007 safe_free(dbuf.dptr);
1009 if (len != dbuf.dsize) {
1010 if (driver.dependentfiles != NULL)
1011 safe_free(driver.dependentfiles);
1013 return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
1016 *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
1021 /****************************************************************************
1022 ****************************************************************************/
1023 uint32 get_a_printer_driver_9x_compatible(pstring line, fstring model)
1025 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1031 slprintf(key, sizeof(key), "%s%s/%d/%s", DRIVERS_PREFIX, "WIN40", 0, model);
1032 DEBUG(10,("driver key: [%s]\n", key));
1035 kbuf.dsize = strlen(key)+1;
1036 if (!tdb_exists(tdb, kbuf)) return False;
1039 get_a_printer_driver_3(&info3, model, "Windows 4.0", 0);
1041 DEBUGADD(10,("info3->name [%s]\n", info3->name));
1042 DEBUGADD(10,("info3->datafile [%s]\n", info3->datafile));
1043 DEBUGADD(10,("info3->helpfile [%s]\n", info3->helpfile));
1044 DEBUGADD(10,("info3->monitorname [%s]\n", info3->monitorname));
1045 DEBUGADD(10,("info3->defaultdatatype [%s]\n", info3->defaultdatatype));
1046 for (i=0; info3->dependentfiles && *info3->dependentfiles[i]; i++) {
1047 DEBUGADD(10,("info3->dependentfiles [%s]\n", info3->dependentfiles[i]));
1049 DEBUGADD(10,("info3->environment [%s]\n", info3->environment));
1050 DEBUGADD(10,("info3->driverpath [%s]\n", info3->driverpath));
1051 DEBUGADD(10,("info3->configfile [%s]\n", info3->configfile));
1053 /*pstrcat(line, info3->name); pstrcat(line, ":");*/
1054 trim_string(info3->configfile, "\\print$\\WIN40\\0\\", 0);
1055 pstrcat(line, info3->configfile);
1057 trim_string(info3->datafile, "\\print$\\WIN40\\0\\", 0);
1058 pstrcat(line, info3->datafile);
1060 trim_string(info3->helpfile, "\\print$\\WIN40\\0\\", 0);
1061 pstrcat(line, info3->helpfile);
1063 trim_string(info3->monitorname, "\\print$\\WIN40\\0\\", 0);
1064 pstrcat(line, info3->monitorname);
1066 pstrcat(line, "RAW"); /*info3->defaultdatatype);*/
1069 for (i=0; info3->dependentfiles &&
1070 *info3->dependentfiles[i]; i++) {
1071 if (i) pstrcat(line, ","); /* don't end in a "," */
1072 trim_string(info3->dependentfiles[i], "\\print$\\WIN40\\0\\", 0);
1073 pstrcat(line, info3->dependentfiles[i]);
1081 /****************************************************************************
1082 debugging function, dump at level 6 the struct in the logs
1083 ****************************************************************************/
1084 static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1087 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
1090 DEBUG(106,("Dumping printer driver at level [%d]\n", level));
1096 if (driver.info_3 == NULL)
1099 info3=driver.info_3;
1101 DEBUGADD(106,("version:[%d]\n", info3->cversion));
1102 DEBUGADD(106,("name:[%s]\n", info3->name));
1103 DEBUGADD(106,("environment:[%s]\n", info3->environment));
1104 DEBUGADD(106,("driverpath:[%s]\n", info3->driverpath));
1105 DEBUGADD(106,("datafile:[%s]\n", info3->datafile));
1106 DEBUGADD(106,("configfile:[%s]\n", info3->configfile));
1107 DEBUGADD(106,("helpfile:[%s]\n", info3->helpfile));
1108 DEBUGADD(106,("monitorname:[%s]\n", info3->monitorname));
1109 DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
1111 for (i=0; info3->dependentfiles &&
1112 *info3->dependentfiles[i]; i++) {
1113 DEBUGADD(106,("dependentfile:[%s]\n",
1114 info3->dependentfiles[i]));
1121 DEBUGADD(1,("Level not implemented\n"));
1129 /****************************************************************************
1130 ****************************************************************************/
1131 static int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
1135 len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
1137 if (!nt_devmode) return len;
1139 len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
1140 nt_devmode->devicename,
1141 nt_devmode->formname,
1143 nt_devmode->specversion,
1144 nt_devmode->driverversion,
1146 nt_devmode->driverextra,
1147 nt_devmode->orientation,
1148 nt_devmode->papersize,
1149 nt_devmode->paperlength,
1150 nt_devmode->paperwidth,
1153 nt_devmode->defaultsource,
1154 nt_devmode->printquality,
1157 nt_devmode->yresolution,
1158 nt_devmode->ttoption,
1159 nt_devmode->collate,
1160 nt_devmode->logpixels,
1163 nt_devmode->bitsperpel,
1164 nt_devmode->pelswidth,
1165 nt_devmode->pelsheight,
1166 nt_devmode->displayflags,
1167 nt_devmode->displayfrequency,
1168 nt_devmode->icmmethod,
1169 nt_devmode->icmintent,
1170 nt_devmode->mediatype,
1171 nt_devmode->dithertype,
1172 nt_devmode->reserved1,
1173 nt_devmode->reserved2,
1174 nt_devmode->panningwidth,
1175 nt_devmode->panningheight,
1176 nt_devmode->private);
1179 if (nt_devmode->private) {
1180 len += tdb_pack(buf+len, buflen-len, "B",
1181 nt_devmode->driverextra,
1182 nt_devmode->private);
1185 DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname));
1190 /****************************************************************************
1191 ****************************************************************************/
1192 static int pack_specifics(NT_PRINTER_PARAM *param, char *buf, int buflen)
1196 while (param != NULL) {
1197 len += tdb_pack(buf+len, buflen-len, "pfdB",
1206 len += tdb_pack(buf+len, buflen-len, "p", param);
1212 /****************************************************************************
1213 delete a printer - this just deletes the printer info file, any open
1214 handles are not affected
1215 ****************************************************************************/
1216 uint32 del_a_printer(char *sharename)
1221 slprintf(key, sizeof(key), "%s%s",
1222 PRINTERS_PREFIX, sharename);
1225 kbuf.dsize=strlen(key)+1;
1227 tdb_delete(tdb, kbuf);
1231 /****************************************************************************
1232 ****************************************************************************/
1233 static uint32 add_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
1237 int buflen, len, ret;
1238 TDB_DATA kbuf, dbuf;
1240 time_t time_unix = time(NULL);
1243 * in addprinter: no servername and the printer is the name
1244 * in setprinter: servername is \\server
1245 * and printer is \\server\\printer
1247 * Samba manages only local printers.
1248 * we currently don't support things like path=\\other_server\printer
1251 if (info->servername[0]!='\0') {
1252 trim_string(info->printername, info->servername, NULL);
1253 trim_string(info->printername, "\\", NULL);
1254 info->servername[0]='\0';
1258 * JFM: one day I'll forget.
1259 * below that's info->portname because that's the SAMBA sharename
1260 * and I made NT 'thinks' it's the portname
1261 * the info->sharename is the thing you can name when you add a printer
1262 * that's the short-name when you create shared printer for 95/98
1263 * So I've made a limitation in SAMBA: you can only have 1 printer model
1264 * behind a SAMBA share.
1267 unix_to_nt_time(&time_nt, time_unix);
1268 info->changeid=time_nt.low;
1269 info->c_setprinter++;
1276 len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffPfffff",
1279 info->default_priority,
1296 info->printprocessor,
1300 len += pack_devicemode(info->devmode, buf+len, buflen-len);
1301 len += pack_specifics(info->specific, buf+len, buflen-len);
1303 if (buflen != len) {
1304 buf = (char *)Realloc(buf, len);
1310 slprintf(key, sizeof(key), "%s%s",
1311 PRINTERS_PREFIX, info->sharename);
1314 kbuf.dsize = strlen(key)+1;
1318 ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
1321 DEBUG(8, ("error updating printer to tdb on disk\n"));
1325 DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n",
1326 info->sharename, info->drivername, info->portname, len));
1332 /****************************************************************************
1333 ****************************************************************************/
1334 BOOL add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
1336 NT_PRINTER_PARAM *current;
1338 DEBUG(108,("add_a_specific_param\n"));
1342 if (info_2->specific == NULL)
1344 info_2->specific=param;
1348 current=info_2->specific;
1349 while (current->next != NULL) {
1350 current=current->next;
1352 current->next=param;
1357 /****************************************************************************
1358 ****************************************************************************/
1359 BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param)
1361 NT_PRINTER_PARAM *current;
1362 NT_PRINTER_PARAM *previous;
1364 current=info_2->specific;
1367 if (current==NULL) return (False);
1369 if ( !strcmp(current->value, param->value) &&
1370 (strlen(current->value)==strlen(param->value)) ) {
1371 DEBUG(109,("deleting first value\n"));
1372 info_2->specific=current->next;
1373 safe_free(current->data);
1375 DEBUG(109,("deleted first value\n"));
1379 current=previous->next;
1381 while ( current!=NULL ) {
1382 if (!strcmp(current->value, param->value) &&
1383 strlen(current->value)==strlen(param->value) ) {
1384 DEBUG(109,("deleting current value\n"));
1385 previous->next=current->next;
1386 safe_free(current->data);
1388 DEBUG(109,("deleted current value\n"));
1392 previous=previous->next;
1393 current=current->next;
1398 /****************************************************************************
1399 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_PARAM.
1400 ****************************************************************************/
1401 static void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr)
1403 NT_PRINTER_PARAM *param = *param_ptr;
1408 DEBUG(106,("free_nt_printer_param: deleting param [%s]\n", param->value));
1411 safe_free(param->data);
1417 /****************************************************************************
1418 Malloc and return an NT devicemode.
1419 ****************************************************************************/
1421 NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
1424 * should I init this ones ???
1425 nt_devmode->devicename
1429 NT_DEVICEMODE *nt_devmode = (NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE));
1431 if (nt_devmode == NULL) {
1432 DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
1436 ZERO_STRUCTP(nt_devmode);
1438 snprintf(adevice, sizeof(adevice), "\\\\%s\\%s", global_myname, default_devicename);
1439 fstrcpy(nt_devmode->devicename, adevice);
1442 fstrcpy(nt_devmode->formname, "Letter");
1444 nt_devmode->specversion = 0x0401;
1445 nt_devmode->driverversion = 0x0400;
1446 nt_devmode->size = 0x00DC;
1447 nt_devmode->driverextra = 0x0000;
1448 nt_devmode->fields = FORMNAME | TTOPTION | PRINTQUALITY |
1449 DEFAULTSOURCE | COPIES | SCALE |
1450 PAPERSIZE | ORIENTATION;
1451 nt_devmode->orientation = 1;
1452 nt_devmode->papersize = PAPER_LETTER;
1453 nt_devmode->paperlength = 0;
1454 nt_devmode->paperwidth = 0;
1455 nt_devmode->scale = 0x64;
1456 nt_devmode->copies = 01;
1457 nt_devmode->defaultsource = BIN_FORMSOURCE;
1458 nt_devmode->printquality = RES_HIGH; /* 0x0258 */
1459 nt_devmode->color = COLOR_MONOCHROME;
1460 nt_devmode->duplex = DUP_SIMPLEX;
1461 nt_devmode->yresolution = 0;
1462 nt_devmode->ttoption = TT_SUBDEV;
1463 nt_devmode->collate = COLLATE_FALSE;
1464 nt_devmode->icmmethod = 0;
1465 nt_devmode->icmintent = 0;
1466 nt_devmode->mediatype = 0;
1467 nt_devmode->dithertype = 0;
1469 /* non utilisés par un driver d'imprimante */
1470 nt_devmode->logpixels = 0;
1471 nt_devmode->bitsperpel = 0;
1472 nt_devmode->pelswidth = 0;
1473 nt_devmode->pelsheight = 0;
1474 nt_devmode->displayflags = 0;
1475 nt_devmode->displayfrequency = 0;
1476 nt_devmode->reserved1 = 0;
1477 nt_devmode->reserved2 = 0;
1478 nt_devmode->panningwidth = 0;
1479 nt_devmode->panningheight = 0;
1481 nt_devmode->private=NULL;
1486 /****************************************************************************
1487 Deepcopy an NT devicemode.
1488 ****************************************************************************/
1490 NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
1492 NT_DEVICEMODE *new_nt_devicemode = NULL;
1494 if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
1495 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
1499 new_nt_devicemode->private = NULL;
1500 if (nt_devicemode->private != NULL) {
1501 if ((new_nt_devicemode->private = memdup(nt_devicemode->private, nt_devicemode->driverextra)) == NULL) {
1502 safe_free(new_nt_devicemode);
1503 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
1508 return new_nt_devicemode;
1511 /****************************************************************************
1512 Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
1513 ****************************************************************************/
1515 void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
1517 NT_DEVICEMODE *nt_devmode = *devmode_ptr;
1519 if(nt_devmode == NULL)
1522 DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
1524 if(nt_devmode->private)
1525 safe_free(nt_devmode->private);
1527 safe_free(nt_devmode);
1528 *devmode_ptr = NULL;
1531 /****************************************************************************
1532 Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
1533 ****************************************************************************/
1534 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
1536 NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
1537 NT_PRINTER_PARAM *param_ptr;
1542 DEBUG(106,("free_nt_printer_info_level_2: deleting info\n"));
1544 free_nt_devicemode(&info->devmode);
1545 free_sec_desc_buf(&info->secdesc_buf);
1547 for(param_ptr = info->specific; param_ptr; ) {
1548 NT_PRINTER_PARAM *tofree = param_ptr;
1550 param_ptr = param_ptr->next;
1551 free_nt_printer_param(&tofree);
1554 safe_free(*info_ptr);
1559 /****************************************************************************
1560 ****************************************************************************/
1561 static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
1565 NT_DEVICEMODE devmode;
1567 ZERO_STRUCT(devmode);
1569 len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
1571 if (!*nt_devmode) return len;
1573 len += tdb_unpack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
1577 &devmode.specversion,
1578 &devmode.driverversion,
1580 &devmode.driverextra,
1581 &devmode.orientation,
1583 &devmode.paperlength,
1584 &devmode.paperwidth,
1587 &devmode.defaultsource,
1588 &devmode.printquality,
1591 &devmode.yresolution,
1597 &devmode.bitsperpel,
1599 &devmode.pelsheight,
1600 &devmode.displayflags,
1601 &devmode.displayfrequency,
1605 &devmode.dithertype,
1608 &devmode.panningwidth,
1609 &devmode.panningheight,
1612 if (devmode.private) {
1613 /* the len in tdb_unpack is an int value and
1614 * devmoce.driverextra is only a short
1616 len += tdb_unpack(buf+len, buflen-len, "B", &extra_len, &devmode.private);
1617 devmode.driverextra=(uint16)extra_len;
1620 *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
1622 DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode.devicename, devmode.formname));
1623 if (devmode.private)
1624 DEBUG(8,("with a private section of %d bytes\n", devmode.driverextra));
1629 /****************************************************************************
1630 ****************************************************************************/
1631 static int unpack_specifics(NT_PRINTER_PARAM **list, char *buf, int buflen)
1634 NT_PRINTER_PARAM param, *p;
1639 len += tdb_unpack(buf+len, buflen-len, "p", &p);
1642 len += tdb_unpack(buf+len, buflen-len, "fdB",
1648 *list = memdup(¶m, sizeof(param));
1650 DEBUG(8,("specific: [%s], len: %d\n", param.value, param.data_len));
1657 /****************************************************************************
1658 get a default printer info 2 struct
1659 ****************************************************************************/
1660 static uint32 get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
1662 extern pstring global_myname;
1664 NT_PRINTER_INFO_LEVEL_2 info;
1668 snum = lp_servicenumber(sharename);
1670 fstrcpy(info.servername, global_myname);
1671 fstrcpy(info.printername, sharename);
1672 fstrcpy(info.portname, SAMBA_PRINTER_PORT_NAME);
1673 fstrcpy(info.drivername, lp_printerdriver(snum));
1674 pstrcpy(info.comment, "");
1675 fstrcpy(info.printprocessor, "winprint");
1676 fstrcpy(info.datatype, "RAW");
1678 info.attributes = PRINTER_ATTRIBUTE_SHARED \
1679 | PRINTER_ATTRIBUTE_LOCAL \
1680 | PRINTER_ATTRIBUTE_RAW_ONLY \
1681 | PRINTER_ATTRIBUTE_QUEUED ; /* attributes */
1683 info.starttime = 0; /* Minutes since 12:00am GMT */
1684 info.untiltime = 0; /* Minutes since 12:00am GMT */
1686 info.default_priority = 1;
1688 if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
1691 if (!nt_printing_getsec(sharename, &info.secdesc_buf))
1694 *info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
1696 DEBUG(0,("get_a_printer_2_default: malloc fail.\n"));
1705 free_nt_devicemode(&info.devmode);
1706 if (info.secdesc_buf)
1707 free_sec_desc_buf(&info.secdesc_buf);
1711 /****************************************************************************
1712 ****************************************************************************/
1713 static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
1716 NT_PRINTER_INFO_LEVEL_2 info;
1718 TDB_DATA kbuf, dbuf;
1722 slprintf(key, sizeof(key), "%s%s", PRINTERS_PREFIX, sharename);
1725 kbuf.dsize = strlen(key)+1;
1727 dbuf = tdb_fetch(tdb, kbuf);
1730 return get_a_printer_2_default(info_ptr, sharename);
1732 if (!dbuf.dptr) return 1;
1735 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff",
1738 &info.default_priority,
1755 info.printprocessor,
1759 /* Samba has to have shared raw drivers. */
1760 info.attributes |= (PRINTER_ATTRIBUTE_SHARED|PRINTER_ATTRIBUTE_RAW_ONLY);
1762 len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
1763 len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
1766 nt_printing_getsec(sharename, &info.secdesc_buf);
1767 #endif /* JRATEST */
1769 safe_free(dbuf.dptr);
1770 *info_ptr=memdup(&info, sizeof(info));
1772 DEBUG(9,("Unpacked printer [%s] running driver [%s]\n",
1773 sharename, info.drivername));
1779 /****************************************************************************
1780 debugging function, dump at level 6 the struct in the logs
1781 ****************************************************************************/
1782 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1785 NT_PRINTER_INFO_LEVEL_2 *info2;
1787 DEBUG(106,("Dumping printer at level [%d]\n", level));
1793 if (printer.info_2 == NULL)
1797 info2=printer.info_2;
1799 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
1800 DEBUGADD(106,("priority:[%d]\n", info2->priority));
1801 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
1802 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
1803 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
1804 DEBUGADD(106,("status:[%d]\n", info2->status));
1805 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
1806 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
1807 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
1808 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
1809 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
1811 DEBUGADD(106,("servername:[%s]\n", info2->servername));
1812 DEBUGADD(106,("printername:[%s]\n", info2->printername));
1813 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
1814 DEBUGADD(106,("portname:[%s]\n", info2->portname));
1815 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
1816 DEBUGADD(106,("comment:[%s]\n", info2->comment));
1817 DEBUGADD(106,("location:[%s]\n", info2->location));
1818 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
1819 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
1820 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
1821 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
1827 DEBUGADD(1,("Level not implemented\n"));
1835 /****************************************************************************
1836 Get the parameters we can substitute in an NT print job.
1837 ****************************************************************************/
1839 void get_printer_subst_params(int snum, fstring *printername, fstring *sharename, fstring *portname)
1841 NT_PRINTER_INFO_LEVEL *printer = NULL;
1843 **printername = **sharename = **portname = '\0';
1845 if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
1848 fstrcpy(*printername, printer->info_2->printername);
1849 fstrcpy(*sharename, printer->info_2->sharename);
1850 fstrcpy(*portname, printer->info_2->portname);
1852 free_a_printer(&printer, 2);
1856 * The function below are the high level ones.
1857 * only those ones must be called from the spoolss code.
1861 /****************************************************************************
1862 ****************************************************************************/
1863 uint32 add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
1867 dump_a_printer(printer, level);
1873 success=add_a_printer_2(printer.info_2);
1884 /****************************************************************************
1885 Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
1886 ****************************************************************************/
1888 uint32 get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename)
1891 NT_PRINTER_INFO_LEVEL *printer = NULL;
1895 DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
1901 if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
1902 DEBUG(0,("get_a_printer: malloc fail.\n"));
1905 ZERO_STRUCTP(printer);
1906 success=get_a_printer_2(&printer->info_2, sharename);
1908 dump_a_printer(*printer, level);
1909 *pp_printer = printer;
1920 DEBUG(10,("get_a_printer: [%s] level %u returning %u\n", sharename, (unsigned int)level, (unsigned int)success));
1925 /****************************************************************************
1926 Deletes a NT_PRINTER_INFO_LEVEL struct.
1927 ****************************************************************************/
1929 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
1932 NT_PRINTER_INFO_LEVEL *printer = *pp_printer;
1934 DEBUG(104,("freeing a printer at level [%d]\n", level));
1936 if (printer == NULL)
1943 if (printer->info_2 != NULL)
1945 free_nt_printer_info_level_2(&printer->info_2);
1964 /****************************************************************************
1965 ****************************************************************************/
1966 uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
1969 DEBUG(104,("adding a printer at level [%d]\n", level));
1970 dump_a_printer_driver(driver, level);
1976 success=add_a_printer_driver_3(driver.info_3);
1982 success=add_a_printer_driver_6(driver.info_6);
1992 /****************************************************************************
1993 ****************************************************************************/
1994 uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
1995 fstring printername, fstring architecture, uint32 version)
2003 success=get_a_printer_driver_3(&driver->info_3, printername, architecture, version);
2012 dump_a_printer_driver(*driver, level);
2016 /****************************************************************************
2017 ****************************************************************************/
2018 uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
2026 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
2027 if (driver.info_3 != NULL)
2029 info3=driver.info_3;
2030 safe_free(info3->dependentfiles);
2031 ZERO_STRUCTP(info3);
2043 NT_PRINTER_DRIVER_INFO_LEVEL_6 *info6;
2044 if (driver.info_6 != NULL)
2046 info6=driver.info_6;
2047 safe_free(info6->dependentfiles);
2048 safe_free(info6->previousnames);
2049 ZERO_STRUCTP(info6);
2066 /****************************************************************************
2067 ****************************************************************************/
2068 BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
2069 fstring value, uint8 **data, uint32 *type, uint32 *len)
2071 /* right now that's enough ! */
2072 NT_PRINTER_PARAM *param;
2075 param=printer.info_2->specific;
2077 while (param != NULL && i < param_index) {
2085 /* exited because it exist */
2087 StrnCpy(value, param->value, sizeof(fstring)-1);
2088 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
2091 ZERO_STRUCTP(*data);
2092 memcpy(*data, param->data, param->data_len);
2093 *len=param->data_len;
2097 /****************************************************************************
2098 ****************************************************************************/
2099 BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level,
2100 fstring value, uint8 **data, uint32 *type, uint32 *len)
2102 /* right now that's enough ! */
2103 NT_PRINTER_PARAM *param;
2105 DEBUG(105, ("get_specific_param\n"));
2107 param=printer.info_2->specific;
2109 while (param != NULL)
2111 #if 1 /* JRA - I think this should be case insensitive.... */
2112 if ( strequal(value, param->value)
2114 if ( !strcmp(value, param->value)
2116 && strlen(value)==strlen(param->value))
2122 DEBUG(106, ("found one param\n"));
2125 /* exited because it exist */
2128 *data=(uint8 *)malloc(param->data_len*sizeof(uint8));
2131 memcpy(*data, param->data, param->data_len);
2132 *len=param->data_len;
2134 DEBUG(106, ("exit of get_specific_param:true\n"));
2137 DEBUG(106, ("exit of get_specific_param:false\n"));
2141 /****************************************************************************
2142 Store a security desc for a printer.
2143 ****************************************************************************/
2145 uint32 nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
2147 SEC_DESC_BUF *new_secdesc_ctr = NULL;
2148 SEC_DESC_BUF *old_secdesc_ctr = NULL;
2150 TALLOC_CTX *mem_ctx = NULL;
2154 mem_ctx = talloc_init();
2155 if (mem_ctx == NULL)
2158 /* The old owner and group sids of the security descriptor are not
2159 present when new ACEs are added or removed by changing printer
2160 permissions through NT. If they are NULL in the new security
2161 descriptor then copy them over from the old one. */
2163 if (!secdesc_ctr->sec->owner_sid || !secdesc_ctr->sec->grp_sid) {
2164 DOM_SID *owner_sid, *group_sid;
2165 SEC_ACL *dacl, *sacl;
2166 SEC_DESC *psd = NULL;
2169 nt_printing_getsec(printername, &old_secdesc_ctr);
2171 /* Pick out correct owner and group sids */
2173 owner_sid = secdesc_ctr->sec->owner_sid ?
2174 secdesc_ctr->sec->owner_sid :
2175 old_secdesc_ctr->sec->owner_sid;
2177 group_sid = secdesc_ctr->sec->grp_sid ?
2178 secdesc_ctr->sec->grp_sid :
2179 old_secdesc_ctr->sec->grp_sid;
2181 dacl = secdesc_ctr->sec->dacl ?
2182 secdesc_ctr->sec->dacl :
2183 old_secdesc_ctr->sec->dacl;
2185 sacl = secdesc_ctr->sec->sacl ?
2186 secdesc_ctr->sec->sacl :
2187 old_secdesc_ctr->sec->sacl;
2189 /* Make a deep copy of the security descriptor */
2191 psd = make_sec_desc(secdesc_ctr->sec->revision,
2192 secdesc_ctr->sec->type,
2193 owner_sid, group_sid,
2198 new_secdesc_ctr = make_sec_desc_buf(size, psd);
2200 /* Free up memory */
2202 free_sec_desc(&psd);
2203 free_sec_desc_buf(&old_secdesc_ctr);
2206 if (!new_secdesc_ctr) {
2207 new_secdesc_ctr = secdesc_ctr;
2210 /* Store the security descriptor in a tdb */
2212 prs_init(&ps, (uint32)sec_desc_size(new_secdesc_ctr->sec) +
2213 sizeof(SEC_DESC_BUF), 4, mem_ctx, MARSHALL);
2215 if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr,
2217 status = ERROR_INVALID_FUNCTION;
2221 slprintf(key, sizeof(key), "SECDESC/%s", printername);
2223 if (tdb_prs_store(tdb, key, &ps)==0) {
2226 DEBUG(1,("Failed to store secdesc for %s\n", printername));
2227 status = ERROR_INVALID_FUNCTION;
2230 /* Free mallocated memory */
2233 free_sec_desc_buf(&old_secdesc_ctr);
2235 if (new_secdesc_ctr != secdesc_ctr) {
2236 free_sec_desc_buf(&new_secdesc_ctr);
2241 talloc_destroy(mem_ctx);
2245 /****************************************************************************
2246 Construct a default security descriptor buffer for a printer.
2247 ****************************************************************************/
2249 static SEC_DESC_BUF *construct_default_printer_sdb(void)
2253 SEC_ACL *psa = NULL;
2254 SEC_DESC_BUF *sdb = NULL;
2255 SEC_DESC *psd = NULL;
2258 enum SID_NAME_USE name_type;
2260 /* Create an ACE where Everyone is allowed to print */
2262 init_sec_access(&sa, PRINTER_ACE_PRINT);
2263 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
2264 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
2267 /* Make the security descriptor owned by the Administrators group
2268 on the PDC of the domain. */
2270 if (winbind_lookup_name(lp_workgroup(), &owner_sid, &name_type)) {
2271 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
2274 /* Backup plan - make printer owned by admins or root. This should
2275 emulate a lanman printer as security settings can't be
2278 if (!lookup_name( "Printer Administrators", &owner_sid, &name_type) &&
2279 !lookup_name( "Administrators", &owner_sid, &name_type) &&
2280 !lookup_name( "Administrator", &owner_sid, &name_type) &&
2281 !lookup_name("root", &owner_sid, &name_type)) {
2282 sid_copy(&owner_sid, &global_sid_World);
2286 init_sec_access(&sa, PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT);
2287 init_sec_ace(&ace[1], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
2288 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
2290 /* The ACL revision number in rpc_secdesc.h differs from the one
2291 created by NT when setting ACE entries in printer
2292 descriptors. NT4 complains about the property being edited by a
2295 #define NT4_ACL_REVISION 0x2
2297 if ((psa = make_sec_acl(NT4_ACL_REVISION, 2, ace)) != NULL) {
2298 psd = make_sec_desc(SEC_DESC_REVISION,
2299 SEC_DESC_SELF_RELATIVE |
2300 SEC_DESC_DACL_PRESENT,
2302 NULL, psa, &sd_size);
2307 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
2311 sdb = make_sec_desc_buf(sd_size, psd);
2313 DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
2314 (unsigned int)sd_size));
2316 free_sec_desc(&psd);
2320 /****************************************************************************
2321 Get a security desc for a printer.
2322 ****************************************************************************/
2324 BOOL nt_printing_getsec(char *printername, SEC_DESC_BUF **secdesc_ctr)
2327 TALLOC_CTX *mem_ctx = NULL;
2330 mem_ctx = talloc_init();
2331 if (mem_ctx == NULL)
2334 /* Fetch security descriptor from tdb */
2336 slprintf(key, sizeof(key), "SECDESC/%s", printername);
2338 if (tdb_prs_fetch(tdb, key, &ps, mem_ctx)!=0 ||
2339 !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
2341 DEBUG(4,("using default secdesc for %s\n", printername));
2343 if (!(*secdesc_ctr = construct_default_printer_sdb())) {
2344 talloc_destroy(mem_ctx);
2348 talloc_destroy(mem_ctx);
2352 /* If security descriptor is owned by S-1-1-0 and winbindd is up,
2353 this security descriptor has been created when winbindd was
2354 down. Take ownership of security descriptor. */
2356 if (sid_equal((*secdesc_ctr)->sec->owner_sid, &global_sid_World)) {
2358 enum SID_NAME_USE name_type;
2360 /* Change sd owner to workgroup administrator */
2362 if (winbind_lookup_name(lp_workgroup(), &owner_sid,
2364 SEC_DESC_BUF *new_secdesc_ctr = NULL;
2365 SEC_DESC *psd = NULL;
2370 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
2372 psd = make_sec_desc((*secdesc_ctr)->sec->revision,
2373 (*secdesc_ctr)->sec->type,
2375 (*secdesc_ctr)->sec->grp_sid,
2376 (*secdesc_ctr)->sec->sacl,
2377 (*secdesc_ctr)->sec->dacl,
2380 new_secdesc_ctr = make_sec_desc_buf(size, psd);
2382 free_sec_desc(&psd);
2384 /* Swap with other one */
2386 free_sec_desc_buf(secdesc_ctr);
2387 *secdesc_ctr = new_secdesc_ctr;
2391 nt_printing_setsec(printername, *secdesc_ctr);
2396 talloc_destroy(mem_ctx);
2402 1: level not implemented
2403 2: file doesn't exist
2404 3: can't allocate memory
2405 4: can't free memory
2406 5: non existant struct
2410 A printer and a printer driver are 2 different things.
2411 NT manages them separatelly, Samba does the same.
2412 Why ? Simply because it's easier and it makes sense !
2414 Now explanation: You have 3 printers behind your samba server,
2415 2 of them are the same make and model (laser A and B). But laser B
2416 has an 3000 sheet feeder and laser A doesn't such an option.
2417 Your third printer is an old dot-matrix model for the accounting :-).
2419 If the /usr/local/samba/lib directory (default dir), you will have
2420 5 files to describe all of this.
2422 3 files for the printers (1 by printer):
2425 NTprinter_accounting
2426 2 files for the drivers (1 for the laser and 1 for the dot matrix)
2427 NTdriver_printer model X
2428 NTdriver_printer model Y
2430 jfm: I should use this comment for the text file to explain
2431 same thing for the forms BTW.
2432 Je devrais mettre mes commentaires en francais, ca serait mieux :-)
2436 /****************************************************************************
2437 Check a user has permissions to perform the given operation. We use some
2438 constants defined in include/rpc_spoolss.h that look relevant to check
2439 the various actions we perform when checking printer access.
2441 PRINTER_ACCESS_ADMINISTER:
2442 print_queue_pause, print_queue_resume, update_printer_sec,
2443 update_printer, spoolss_addprinterex_level_2,
2444 _spoolss_setprinterdata
2449 JOB_ACCESS_ADMINISTER:
2450 print_job_delete, print_job_pause, print_job_resume,
2453 ****************************************************************************/
2454 BOOL print_access_check(struct current_user *user, int snum, int access_type)
2456 SEC_DESC_BUF *secdesc = NULL;
2457 uint32 access_granted, status, required_access = 0;
2461 extern struct current_user current_user;
2463 /* If user is NULL then use the current_user structure */
2465 if (!user) user = ¤t_user;
2467 /* Always allow root or printer admins to do anything */
2469 if (user->uid == 0 ||
2470 user_in_list(uidtoname(user->uid), lp_printer_admin(snum))) {
2474 /* Get printer name */
2476 pname = PRINTERNAME(snum);
2478 if (!pname || !*pname)
2479 pname = SERVICE(snum);
2481 if (!pname || !*pname) {
2486 /* Get printer security descriptor */
2488 nt_printing_getsec(pname, &secdesc);
2490 /* Check against NT4 ACE mask values. From observation these
2493 Access Type ACE Mask Constant
2494 -------------------------------------
2495 Full Control 0x10000000 PRINTER_ACE_FULL_CONTROL
2496 Print 0xe0000000 PRINTER_ACE_PRINT
2497 Manage Documents 0x00020000 PRINTER_ACE_MANAGE_DOCUMENTS
2500 switch (access_type) {
2501 case PRINTER_ACCESS_USE:
2502 required_access = PRINTER_ACE_PRINT;
2504 case PRINTER_ACCESS_ADMINISTER:
2505 required_access = PRINTER_ACE_MANAGE_DOCUMENTS |
2508 case JOB_ACCESS_ADMINISTER:
2509 required_access = PRINTER_ACE_MANAGE_DOCUMENTS;
2512 DEBUG(0, ("invalid value passed to print_access_check()\n"));
2517 /* The ACE for Full Control in a printer security descriptor
2518 doesn't seem to map properly to the access checking model. For
2519 it to work properly it should be the logical OR of all the other
2520 values, i.e PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT.
2521 This would cause the access check to simply fall out when we
2522 check against any subset of these bits. To get things to work,
2523 change every ACE mask of PRINTER_ACE_FULL_CONTROL to
2524 PRINTER_ACE_MANAGE_DOCUMENTS | PRINTER_ACE_PRINT before
2525 performing the access check. I'm sure there is a better way to
2528 if (secdesc && secdesc->sec && secdesc->sec->dacl &&
2529 secdesc->sec->dacl->ace) {
2530 for(i = 0; i < secdesc->sec->dacl->num_aces; i++) {
2531 if (secdesc->sec->dacl->ace[i].info.mask ==
2532 PRINTER_ACE_FULL_CONTROL) {
2533 secdesc->sec->dacl->ace[i].info.mask =
2534 PRINTER_ACE_MANAGE_DOCUMENTS |
2540 if ((result = se_access_check(secdesc->sec, user, required_access,
2541 &access_granted, &status))) {
2545 /* Check against NT5 ACE mask values. From observation these
2548 Access Type ACE Mask Constant
2549 -------------------------------------
2550 Full Control 0x000f000c PRINTER_ACE_NT5_FULL_CONTROL
2551 Print 0x00020008 PRINTER_ACE_NT5_PRINT
2552 Manage Documents 0x00020000 PRINTER_ACE_NT5_MANAGE_DOCUMENTS
2554 NT5 likes to rewrite the security descriptor and change the ACE
2555 masks from NT4 format to NT5 format making them unreadable by
2558 switch (access_type) {
2559 case PRINTER_ACCESS_USE:
2560 required_access = PRINTER_ACE_NT5_PRINT;
2562 case PRINTER_ACCESS_ADMINISTER:
2563 required_access = PRINTER_ACE_NT5_FULL_CONTROL;
2565 case JOB_ACCESS_ADMINISTER:
2566 required_access = PRINTER_ACE_NT5_MANAGE_DOCUMENTS;
2570 result = se_access_check(secdesc->sec, user, required_access,
2571 &access_granted, &status);
2576 DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE"));
2578 /* Free mallocated memory */
2580 free_sec_desc_buf(&secdesc);
2588 /****************************************************************************
2589 Check the time parameters allow a print operation.
2590 *****************************************************************************/
2592 BOOL print_time_access_check(int snum)
2594 NT_PRINTER_INFO_LEVEL *printer = NULL;
2596 time_t now = time(NULL);
2600 if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
2603 if (printer->info_2->starttime == 0 && printer->info_2->untiltime == 0)
2607 mins = (uint32)t->tm_hour*60 + (uint32)t->tm_min;
2609 if (mins >= printer->info_2->starttime && mins <= printer->info_2->untiltime)
2612 free_a_printer(&printer, 2);