diff options
author | Jean-François Micouleau <jfm@samba.org> | 2000-07-25 13:15:16 +0000 |
---|---|---|
committer | Jean-François Micouleau <jfm@samba.org> | 2000-07-25 13:15:16 +0000 |
commit | 5a5ef183799dd84ff453db849e929533e709fd0b (patch) | |
tree | cf2f652f9c383a5e181e7437b15c36cbf331b64c | |
parent | b40175936ae3d7acd6eb3f386c467ba3f9868631 (diff) | |
download | samba-5a5ef183799dd84ff453db849e929533e709fd0b.tar.gz samba-5a5ef183799dd84ff453db849e929533e709fd0b.tar.bz2 samba-5a5ef183799dd84ff453db849e929533e709fd0b.zip |
A rather big change set ! (listed in no particular order)
- changed the default forms flag to 2
- all short architecture name are uppercased
- get_short_archi() is now case unsensitive
- the drivers TDB is indexed by archi/version/name
- implemented code to move drivers from the upload area to the download
area. Someone else need to look at that code.
- don't return anymore a default driver if it doesn't exist in the TDB.
Instead return an error.
- cleaned prs_unistr.
- #ifdef out jeremy's new SD parsing in printer_info_2
- removed the unused MANGLE_CODE
- #ifdef out the security checking in update_printer() as it doesn't work
for me.
Zap your ntdrivers.tdb, it won't work anymore.
J.F.
(This used to be commit ac0a145acc0953a6f362497abbf4dfe70aa522a6)
-rw-r--r-- | source3/include/proto.h | 15 | ||||
-rw-r--r-- | source3/include/smb.h | 2 | ||||
-rw-r--r-- | source3/printing/nt_printing.c | 274 | ||||
-rw-r--r-- | source3/rpc_parse/parse_prs.c | 57 | ||||
-rw-r--r-- | source3/rpc_parse/parse_spoolss.c | 13 | ||||
-rwxr-xr-x | source3/rpc_server/srv_spoolss.c | 2 | ||||
-rw-r--r-- | source3/rpc_server/srv_spoolss_nt.c | 407 | ||||
-rw-r--r-- | source3/rpcclient/cmd_spoolss.c | 2 | ||||
-rw-r--r-- | source3/smbd/reply.c | 28 |
9 files changed, 494 insertions, 306 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index 696ccf07c6..7a52506451 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1668,8 +1668,10 @@ int get_ntforms(nt_forms_struct **list); int write_ntforms(nt_forms_struct **list, int number); BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count); void update_a_form(nt_forms_struct **list, const FORM *form, int count); -int get_ntdrivers(fstring **list, char *architecture); -void get_short_archi(char *short_archi, char *long_archi); +int get_ntdrivers(fstring **list, char *architecture, uint32 version); +BOOL get_short_archi(char *short_archi, char *long_archi); +uint32 clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level); +uint32 move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level, struct current_user *user); uint32 get_a_printer_driver_9x_compatible(pstring line, fstring model); uint32 del_a_printer(char *sharename); BOOL add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param); @@ -1682,7 +1684,7 @@ uint32 get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring s uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level); uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level); uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level, - fstring printername, fstring architecture); + fstring printername, fstring architecture, uint32 version); uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level); BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index, fstring value, uint8 **data, uint32 *type, uint32 *len); @@ -2319,7 +2321,6 @@ BOOL prs_string2(BOOL charmode, char *name, prs_struct *ps, int depth, STRING2 * BOOL prs_unistr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNISTR2 *str); BOOL prs_unistr3(BOOL charmode, char *name, UNISTR3 *str, prs_struct *ps, int depth); BOOL prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str); -BOOL prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str); BOOL prs_string(char *name, prs_struct *ps, int depth, char *str, int len, int max_buf_size); BOOL prs_uint16_pre(char *name, prs_struct *ps, int depth, uint16 *data16, uint32 *offset); BOOL prs_uint16_post(char *name, prs_struct *ps, int depth, uint16 *data16, @@ -3112,9 +3113,8 @@ uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_name, uint32 level, uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3, uint32 user_switch, const SPOOL_USER_CTR *user, POLICY_HND *handle); -uint32 _spoolss_addprinterdriver( const UNISTR2 *server_name, - uint32 level, - const SPOOL_PRINTER_DRIVER_INFO_LEVEL *info); +uint32 _spoolss_addprinterdriver(pipes_struct *p, const UNISTR2 *server_name, + uint32 level, const SPOOL_PRINTER_DRIVER_INFO_LEVEL *info); uint32 _spoolss_getprinterdriverdirectory(UNISTR2 *name, UNISTR2 *uni_environment, uint32 level, NEW_BUFFER *buffer, uint32 offered, uint32 *needed); @@ -3625,6 +3625,7 @@ int reply_printclose(connection_struct *conn, int reply_printqueue(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize); int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize); +int mkdir_internal(connection_struct *conn, char *inbuf, char *outbuf, pstring directory); int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize); BOOL rmdir_internals(connection_struct *conn, char *directory); int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize); diff --git a/source3/include/smb.h b/source3/include/smb.h index a49bbb9636..bc9f17544c 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -184,8 +184,10 @@ implemented */ #define ERROR_EAS_DIDNT_FIT (275) /* Extended attributes didn't fit */ #define ERROR_EAS_NOT_SUPPORTED (282) /* Extended attributes not supported */ #define ERROR_NOTIFY_ENUM_DIR (1022) /* Buffer too small to return change notify. */ +#define ERROR_UNKNOWN_PRINTER_DRIVER (1797) #define ERROR_INVALID_PRINTER_NAME (1801) #define ERROR_INVALID_DATATYPE (1804) +#define ERROR_INVALID_ENVIRONMENT (1805) /* here's a special one from observing NT */ #define ERRnoipc 66 /* don't support ipc */ diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 9e7862eda0..76ec4d4ace 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -37,8 +37,8 @@ static TDB_CONTEXT *tdb; /* used for driver files */ /* we need to have a small set of default forms to support our default printer */ static nt_forms_struct default_forms[] = { - {"Letter", 0x20, 0x34b5b, 0x44367, 0x0, 0x0, 0x34b5b, 0x44367}, - {"A4", 0xb0, 0x3354f, 0x4884e, 0x0, 0x0, 0x3354f, 0x4884e} + {"Letter", 0x2, 0x34b5b, 0x44367, 0x0, 0x0, 0x34b5b, 0x44367}, + {"A4", 0x2, 0x3354f, 0x4884e, 0x0, 0x0, 0x3354f, 0x4884e} }; @@ -216,7 +216,7 @@ get the nt drivers list traverse the database and look-up the matching names ****************************************************************************/ -int get_ntdrivers(fstring **list, char *architecture) +int get_ntdrivers(fstring **list, char *architecture, uint32 version) { int total=0; fstring short_archi; @@ -224,7 +224,7 @@ int get_ntdrivers(fstring **list, char *architecture) TDB_DATA kbuf, newkey; get_short_archi(short_archi, architecture); - slprintf(key, sizeof(key), "%s%s/", DRIVERS_PREFIX, short_archi); + slprintf(key, sizeof(key), "%s%s/%d/", DRIVERS_PREFIX, short_archi, version); for (kbuf = tdb_firstkey(tdb); kbuf.dptr; @@ -245,7 +245,7 @@ int get_ntdrivers(fstring **list, char *architecture) function to do the mapping between the long architecture name and the short one. ****************************************************************************/ -void get_short_archi(char *short_archi, char *long_archi) +BOOL get_short_archi(char *short_archi, char *long_archi) { struct table { char *long_archi; @@ -256,9 +256,9 @@ void get_short_archi(char *short_archi, char *long_archi) { {"Windows 4.0", "WIN40" }, {"Windows NT x86", "W32X86" }, - {"Windows NT R4000", "W32mips" }, - {"Windows NT Alpha_AXP", "W32alpha" }, - {"Windows NT PowerPC", "W32ppc" }, + {"Windows NT R4000", "W32MIPS" }, + {"Windows NT Alpha_AXP", "W32ALPHA" }, + {"Windows NT PowerPC", "W32PPC" }, {NULL, "" } }; @@ -267,17 +267,192 @@ void get_short_archi(char *short_archi, char *long_archi) DEBUG(107,("Getting architecture dependant directory\n")); do { i++; - } while ( (archi_table[i].long_archi!=NULL ) && strncmp(long_archi, archi_table[i].long_archi, strlen(long_archi)) ); + } while ( (archi_table[i].long_archi!=NULL ) && + StrCaseCmp(long_archi, archi_table[i].long_archi) ); - if (archi_table[i].long_archi==NULL) - { + if (archi_table[i].long_archi==NULL) { DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi)); + return FALSE; } + StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi)); DEBUGADD(108,("index: [%d]\n", i)); DEBUGADD(108,("long architecture: [%s]\n", long_archi)); DEBUGADD(108,("short architecture: [%s]\n", short_archi)); + + return TRUE; +} + +/**************************************************************************** +****************************************************************************/ +static uint32 clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver) +{ + fstring architecture; + fstring new_name; + char *p; + int i; + + /* jfm:7/16/2000 the client always sends the cversion=0. + * The server should check which version the driver is by reading the PE header + * of driver->driverpath. + * + * For Windows 95/98 the version is 0 (so the value sent is correct) + * For Windows NT (the architecture doesn't matter) + * NT 3.1: cversion=0 + * NT 3.5/3.51: cversion=1 + * NT 4: cversion=2 + * NT2K: cversion=3 + */ + + get_short_archi(architecture, driver->environment); + + /* if it's Windows 95/98, we keep the version at 0 + * jfmxxx: I need to redo that more correctly for NT2K. + */ + + if (StrCaseCmp(driver->environment, "Windows 4.0")==0) + driver->cversion=0; + else + driver->cversion=2; + + /* clean up the driver name. + * we can get .\driver.dll + * or worse c:\windows\system\driver.dll ! + */ + /* using an intermediate string to not have overlaping memcpy()'s */ + if ((p = strrchr(driver->driverpath,'\\')) != NULL) { + fstrcpy(new_name, p+1); + fstrcpy(driver->driverpath, new_name); + } + + if ((p = strrchr(driver->datafile,'\\')) != NULL) { + fstrcpy(new_name, p+1); + fstrcpy(driver->datafile, new_name); + } + + if ((p = strrchr(driver->configfile,'\\')) != NULL) { + fstrcpy(new_name, p+1); + fstrcpy(driver->configfile, new_name); + } + + if ((p = strrchr(driver->helpfile,'\\')) != NULL) { + fstrcpy(new_name, p+1); + fstrcpy(driver->helpfile, new_name); + } + + if (driver->dependentfiles) { + for (i=0; *driver->dependentfiles[i]; i++) { + if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) { + fstrcpy(new_name, p+1); + fstrcpy(driver->dependentfiles[i], new_name); + } + } + } +} + +/**************************************************************************** +****************************************************************************/ +static uint32 clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver) +{ + +} + +/**************************************************************************** +****************************************************************************/ +uint32 clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level) +{ + switch (level) { + case 3: + { + NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver; + driver=driver_abstract.info_3; + clean_up_driver_struct_level_3(driver); + break; + } + case 6: + { + NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver; + driver=driver_abstract.info_6; + clean_up_driver_struct_level_6(driver); + break; + } + } +} + +/**************************************************************************** +****************************************************************************/ +uint32 move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level, struct current_user *user) +{ + NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver; + fstring architecture; + fstring clean_driver_name; + pstring new_dir; + pstring old_name; + pstring new_name; + connection_struct *conn; + fstring inbuf; + fstring outbuf; + struct smb_passwd *smb_pass; + int ecode; + int outsize = 0; + int i; + + if (level==3) + driver=driver_abstract.info_3; + + get_short_archi(architecture, driver->environment); + + /* clean up the driver's name */ + fstrcpy(clean_driver_name, driver->name); + all_string_sub(clean_driver_name, "/", "#", 0); + + /* connect to the print$ share under the same account as the user connected to the rpc pipe */ + smb_pass = getsmbpwnam(uidtoname(user->uid)); + conn = make_connection("print$", uidtoname(user->uid), smb_pass->smb_nt_passwd, 24, "A:", user->vuid, &ecode); + + /* + * make the directories version and version\driver_name + * under the architecture directory. + */ + DEBUG(5,("Creating first directory\n")); + slprintf(new_dir, sizeof(new_dir), "%s\\%d", architecture, driver->cversion); + mkdir_internal(conn, inbuf, outbuf, new_dir); + + slprintf(new_dir, sizeof(new_dir), "%s\\%d\\%s", architecture, driver->cversion, clean_driver_name); + mkdir_internal(conn, inbuf, outbuf, new_dir); + + /* move all the files, one by one, + * from archi\filexxx.yyy to + * archi\version\driver name\filexxx.yyy + */ + + DEBUG(5,("Moving file now !\n")); + slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->driverpath); + slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->driverpath); + outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, False); + + slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->datafile); + slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->datafile); + outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, False); + + slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->configfile); + slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->configfile); + outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, False); + + slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->helpfile); + slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->helpfile); + outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, False); + + if (driver->dependentfiles) { + for (i=0; *driver->dependentfiles[i]; i++) { + slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->dependentfiles[i]); + slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->dependentfiles[i]); + outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, False); + } + } + + close_cnum(conn, user->vuid); } /**************************************************************************** @@ -286,24 +461,49 @@ static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver) { int len, buflen; fstring architecture; + pstring directory; + fstring clean_driver_name; + pstring temp_name; pstring key; char *buf; int i, ret; TDB_DATA kbuf, dbuf; get_short_archi(architecture, driver->environment); - slprintf(key, sizeof(key), "%s%s/%s", DRIVERS_PREFIX, architecture, driver->name); - /* - * cversion must be 2. - * when adding a printer ON the SERVER - * rpcAddPrinterDriver defines it to zero - * which is wrong !!! - * - * JFM, 4/14/99 + /* The names are relative. We store them in the form: \print$\arch\version\printer-name\driver.xxx + * \\server is added in the rpc server layer. + * It does make sense to NOT store the server's name in the printer TDB. */ - driver->cversion=2; + + /* clean up the driver's name */ + fstrcpy(clean_driver_name, driver->name); + all_string_sub(clean_driver_name, "/", "#", 0); + + slprintf(directory, sizeof(directory), "\\print$\\%s\\%d\\%s\\", architecture, driver->cversion, clean_driver_name); + + fstrcpy(temp_name, driver->driverpath); + slprintf(driver->driverpath, sizeof(driver->driverpath), "%s%s", directory, temp_name); + + fstrcpy(temp_name, driver->datafile); + slprintf(driver->datafile, sizeof(driver->datafile), "%s%s", directory, temp_name); + + fstrcpy(temp_name, driver->configfile); + slprintf(driver->configfile, sizeof(driver->configfile), "%s%s", directory, temp_name); + + fstrcpy(temp_name, driver->helpfile); + slprintf(driver->helpfile, sizeof(driver->helpfile), "%s%s", directory, temp_name); + + if (driver->dependentfiles) { + for (i=0; *driver->dependentfiles[i]; i++) { + fstrcpy(temp_name, driver->dependentfiles[i]); + slprintf(driver->dependentfiles[i], sizeof(driver->dependentfiles[i]), "%s%s", directory, temp_name); + } + } + + slprintf(key, sizeof(key), "%s%s/%d/%s", DRIVERS_PREFIX, architecture, driver->cversion, driver->name); + buf = NULL; len = buflen = 0; @@ -319,7 +519,7 @@ static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver) driver->helpfile, driver->monitorname, driver->defaultdatatype); - + if (driver->dependentfiles) { for (i=0; *driver->dependentfiles[i]; i++) { len += tdb_pack(buf+len, buflen-len, "f", @@ -395,7 +595,7 @@ static uint32 get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **in /**************************************************************************** ****************************************************************************/ -static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch) +static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch, uint32 version) { NT_PRINTER_DRIVER_INFO_LEVEL_3 driver; TDB_DATA kbuf, dbuf; @@ -407,14 +607,20 @@ static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, ZERO_STRUCT(driver); get_short_archi(architecture, in_arch); - slprintf(key, sizeof(key), "%s%s/%s", DRIVERS_PREFIX, architecture, in_prt); + + DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, in_prt)); + + slprintf(key, sizeof(key), "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, in_prt); kbuf.dptr = key; kbuf.dsize = strlen(key)+1; dbuf = tdb_fetch(tdb, kbuf); +#if 0 if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch); - +#else + if (!dbuf.dptr) return 5; +#endif len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff", &driver.cversion, driver.name, @@ -464,7 +670,7 @@ uint32 get_a_printer_driver_9x_compatible(pstring line, fstring model) int i; line[0] = '\0'; - slprintf(key, sizeof(key), "%s%s/%s", DRIVERS_PREFIX, "WIN40", model); + slprintf(key, sizeof(key), "%s%s/%d/%s", DRIVERS_PREFIX, "WIN40", 0, model); DEBUG(10,("driver key: [%s]\n", key)); kbuf.dptr = key; @@ -472,7 +678,7 @@ uint32 get_a_printer_driver_9x_compatible(pstring line, fstring model) if (!tdb_exists(tdb, kbuf)) return False; ZERO_STRUCT(info3); - get_a_printer_driver_3(&info3, model, "Windows 4.0"); + get_a_printer_driver_3(&info3, model, "Windows 4.0", 0); DEBUGADD(10,("info3->name [%s]\n", info3->name)); DEBUGADD(10,("info3->datafile [%s]\n", info3->datafile)); @@ -754,7 +960,7 @@ static uint32 add_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info) safe_free(buf); DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n", - info->portname, info->drivername, info->portname, len)); + info->sharename, info->drivername, info->portname, len)); return ret; } @@ -1071,6 +1277,8 @@ static int unpack_specifics(NT_PRINTER_PARAM **list, char *buf, int buflen) ¶m.data); param.next = *list; *list = memdup(¶m, sizeof(param)); + + DEBUG(8,("specific: [%s], len: %d\n", param.value, param.data_len)); } return len; @@ -1110,8 +1318,10 @@ static uint32 get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstrin if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL) goto fail; +#if 1 if (!nt_printing_getsec(sharename, &info.secdesc_buf)) goto fail; +#endif *info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info)); if (! *info_ptr) { @@ -1141,8 +1351,7 @@ static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharen ZERO_STRUCT(info); - slprintf(key, sizeof(key), "%s%s", - PRINTERS_PREFIX, sharename); + slprintf(key, sizeof(key), "%s%s", PRINTERS_PREFIX, sharename); kbuf.dptr = key; kbuf.dsize = strlen(key)+1; @@ -1184,7 +1393,9 @@ static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharen len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len); len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len); +#if 1 /* JRATEST */ nt_printing_getsec(sharename, &info.secdesc_buf); +#endif /* JRATEST */ safe_free(dbuf.dptr); *info_ptr=memdup(&info, sizeof(info)); @@ -1393,7 +1604,7 @@ uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level) /**************************************************************************** ****************************************************************************/ uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level, - fstring printername, fstring architecture) + fstring printername, fstring architecture, uint32 version) { uint32 success; @@ -1403,7 +1614,7 @@ uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level, { success=get_a_printer_driver_3(&(driver->info_3), printername, - architecture); + architecture, version); break; } default: @@ -1645,6 +1856,7 @@ static SEC_DESC_BUF *construct_default_printer_sdb(void) init_sec_ace(&ace, &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, sa, SEC_ACE_FLAG_CONTAINER_INHERIT); + /* Make the security descriptor owned by the Administrators group on the PDC of the domain. */ diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c index 5f43e52975..42a3410752 100644 --- a/source3/rpc_parse/parse_prs.c +++ b/source3/rpc_parse/parse_prs.c @@ -628,61 +628,6 @@ BOOL prs_unistr3(BOOL charmode, char *name, UNISTR3 *str, prs_struct *ps, int de in little-endian format then do it as a stream of bytes. ********************************************************************/ -#ifndef RPCCLIENT_TEST -BOOL prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str) -{ - int len = 0; - unsigned char *p = (unsigned char *)str->buffer; - uint8 *start; - char *q; - char zero=0; - - for(len = 0; len < (sizeof(str->buffer) / sizeof(str->buffer[0])) && - str->buffer[len] != 0; len++) - ; - - q = prs_mem_get(ps, (len+1)*2); - if (q == NULL) - return False; - - start = (uint8*)q; - - for(len = 0; len < (sizeof(str->buffer) / sizeof(str->buffer[0])) && - str->buffer[len] != 0; len++) { - if(ps->bigendian_data) { - RW_SVAL(ps->io, ps->bigendian_data, q, *p, 0); - p += 2; - q += 2; - } else { - RW_CVAL(ps->io, q, *p, 0); - p++; - q++; - RW_CVAL(ps->io, q, *p, 0); - p++; - q++; - } - } - - /* - * even if the string is 'empty' (only an \0 char) - * at this point the leading \0 hasn't been parsed. - * so parse it now - */ - - RW_CVAL(ps->io, q, zero, 0); - q++; - RW_CVAL(ps->io, q, zero, 0); - q++; - - len++; - - ps->data_offset += len*2; - - dump_data(5+depth, (char *)start, len * 2); - - return True; -} -#else BOOL prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str) { int len = 0; @@ -769,8 +714,6 @@ BOOL prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str) return True; } -#endif /* RPCCLIENT_TEST */ - /******************************************************************* Stream a null-terminated string. len is strlen, and therefore does diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index fd120a57ec..b0223d2803 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -1791,8 +1791,13 @@ BOOL new_smb_io_printer_info_2(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *i if (!new_smb_io_relstr("parameters", buffer, depth, &info->parameters)) return False; - if (!prs_uint32_pre("secdesc_ptr ", ps, depth, &i, &sec_offset)) +#if 0 /* JFMTEST */ + if (!prs_uint32_pre("secdesc_ptr ", ps, depth, NULL, &sec_offset)) return False; +#else + if (!new_smb_io_relsecdesc("secdesc", buffer, depth, &info->secdesc)) + return False; +#endif if (!prs_uint32("attributes", ps, depth, &info->attributes)) return False; @@ -1811,12 +1816,13 @@ BOOL new_smb_io_printer_info_2(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *i if (!prs_uint32("averageppm", ps, depth, &info->averageppm)) return False; - if (!prs_uint32_post("secdesc_ptr", ps, depth, &i, sec_offset, info->secdesc ? prs_offset(ps) : 0 )) +#if 0 /* JFMTEST */ + if (!prs_uint32_post("secdesc_ptr", ps, depth, NULL, sec_offset, info->secdesc ? prs_offset(ps)-buffer->struct_start : 0 )) return False; if (!sec_io_desc("secdesc", &info->secdesc, ps, depth)) return False; - +#endif return True; } @@ -4285,7 +4291,6 @@ BOOL make_spoolss_q_getprinterdriverdir(SPOOL_Q_GETPRINTERDRIVERDIR *q_u, NEW_BUFFER *buffer, uint32 offered) { init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername); - init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, env_name); q_u->level=level; diff --git a/source3/rpc_server/srv_spoolss.c b/source3/rpc_server/srv_spoolss.c index 3f72305465..8b431551b5 100755 --- a/source3/rpc_server/srv_spoolss.c +++ b/source3/rpc_server/srv_spoolss.c @@ -880,7 +880,7 @@ static BOOL api_spoolss_addprinterdriver(pipes_struct *p) return False; } - r_u.status = _spoolss_addprinterdriver(&q_u.server_name, q_u.level, &q_u.info); + r_u.status = _spoolss_addprinterdriver(p, &q_u.server_name, q_u.level, &q_u.info); if(!spoolss_io_r_addprinterdriver("", &r_u, rdata, 0)) { DEBUG(0,("spoolss_io_r_addprinterdriver: unable to marshall SPOOL_R_ADDPRINTERDRIVER.\n")); diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 7d5036c6d4..99ed18677a 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -25,10 +25,6 @@ #include "includes.h" -#ifndef MANGLE_DRIVER_PATH -#define MANGLE_DRIVER_PATH 0 -#endif - extern int DEBUGLEVEL; extern pstring global_myname; @@ -2479,73 +2475,66 @@ uint32 _spoolss_getprinter(POLICY_HND *handle, uint32 level, } /******************************************************************** - * construct_printer_driver_info_1 - * fill a construct_printer_driver_info_1 struct + * fill a DRIVER_INFO_1 struct ********************************************************************/ -static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, - NT_PRINTER_DRIVER_INFO_LEVEL driver, - fstring servername, fstring architecture) +static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername, fstring architecture) { init_unistr( &(info->name), driver.info_3->name); } -static void construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, - fstring servername, fstring architecture) +/******************************************************************** + * construct_printer_driver_info_1 + ********************************************************************/ +static uint32 construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, fstring servername, fstring architecture, uint32 version) { NT_PRINTER_INFO_LEVEL *printer = NULL; NT_PRINTER_DRIVER_INFO_LEVEL driver; ZERO_STRUCT(driver); - get_a_printer(&printer, 2, lp_servicename(snum) ); - get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture); - + if (get_a_printer(&printer, 2, lp_servicename(snum)) != 0) + return ERROR_INVALID_PRINTER_NAME; + + if (get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version) != 0) + return ERROR_UNKNOWN_PRINTER_DRIVER; + fill_printer_driver_info_1(info, driver, servername, architecture); free_a_printer(&printer,2); + + return NT_STATUS_NO_PROBLEMO; } /******************************************************************** * construct_printer_driver_info_2 * fill a printer_info_2 struct ********************************************************************/ -static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, - NT_PRINTER_DRIVER_INFO_LEVEL driver, - fstring servername, fstring architecture) +static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername) { - pstring where; pstring temp_driverpath; pstring temp_datafile; pstring temp_configfile; - fstring short_archi; - - get_short_archi(short_archi,architecture); - - snprintf(where,sizeof(where)-1,"\\\\%s\\print$\\%s\\", servername, short_archi); info->version=driver.info_3->cversion; - init_unistr( &info->name, driver.info_3->name ); - init_unistr( &info->architecture, architecture ); - - snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "%s%s", where, - driver.info_3->driverpath); - init_unistr( &info->driverpath, temp_driverpath ); + init_unistr( &info->name, driver.info_3->name ); + init_unistr( &info->architecture, driver.info_3->environment ); - snprintf(temp_datafile, sizeof(temp_datafile)-1, "%s%s", where, - driver.info_3->datafile); - init_unistr( &info->datafile, temp_datafile ); + snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "\\\\%s%s", servername, driver.info_3->driverpath); + init_unistr( &info->driverpath, temp_driverpath ); - snprintf(temp_configfile, sizeof(temp_configfile)-1, "%s%s", where, - driver.info_3->configfile); - init_unistr( &info->configfile, temp_configfile ); + snprintf(temp_datafile, sizeof(temp_datafile)-1, "\\\\%s%s", servername, driver.info_3->datafile); + init_unistr( &info->datafile, temp_datafile ); + + snprintf(temp_configfile, sizeof(temp_configfile)-1, "\\\\%s%s", servername, driver.info_3->configfile); + init_unistr( &info->configfile, temp_configfile ); } /******************************************************************** * construct_printer_driver_info_2 * fill a printer_info_2 struct ********************************************************************/ -static void construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, fstring servername, fstring architecture) +static uint32 construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, fstring servername, fstring architecture, uint32 version) { NT_PRINTER_INFO_LEVEL *printer = NULL; NT_PRINTER_DRIVER_INFO_LEVEL driver; @@ -2553,12 +2542,17 @@ static void construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, fstri ZERO_STRUCT(printer); ZERO_STRUCT(driver); - get_a_printer(&printer, 2, lp_servicename(snum) ); - get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture); + if (!get_a_printer(&printer, 2, lp_servicename(snum)) != 0) + return ERROR_INVALID_PRINTER_NAME; + + if (!get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version) != 0) + return ERROR_UNKNOWN_PRINTER_DRIVER; - fill_printer_driver_info_2(info, driver, servername, architecture); + fill_printer_driver_info_2(info, driver, servername); free_a_printer(&printer,2); + + return NT_STATUS_NO_PROBLEMO; } /******************************************************************** @@ -2566,7 +2560,7 @@ static void construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, fstri * * convert an array of ascii string to a UNICODE string ********************************************************************/ -static void init_unistr_array(uint16 **uni_array, fstring *char_array, char *where) +static void init_unistr_array(uint16 **uni_array, fstring *char_array, char *servername) { int i=0; int j=0; @@ -2584,7 +2578,7 @@ static void init_unistr_array(uint16 **uni_array, fstring *char_array, char *whe if (!v) v = ""; /* hack to handle null lists */ } if (strlen(v) == 0) break; - snprintf(line, sizeof(line)-1, "%s%s", where, v); + snprintf(line, sizeof(line)-1, "\\\\%s%s", servername, v); DEBUGADD(6,("%d:%s:%d\n", i, line, strlen(line))); if((*uni_array=Realloc(*uni_array, (j+strlen(line)+2)*sizeof(uint16))) == NULL) { DEBUG(0,("init_unistr_array: Realloc error\n" )); @@ -2605,67 +2599,63 @@ static void init_unistr_array(uint16 **uni_array, fstring *char_array, char *whe * construct_printer_info_3 * fill a printer_info_3 struct ********************************************************************/ -static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, - NT_PRINTER_DRIVER_INFO_LEVEL driver, - fstring servername, fstring architecture) +static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername) { - pstring where; pstring temp_driverpath; pstring temp_datafile; pstring temp_configfile; pstring temp_helpfile; - fstring short_archi; - - get_short_archi(short_archi, architecture); - -#if MANGLE_DRIVER_PATH - snprintf(where,sizeof(where)-1,"\\\\%s\\print$\\%s\\%s\\", servername, short_archi, driver.info_3->name); -#else - snprintf(where,sizeof(where)-1,"\\\\%s\\print$\\%s\\", servername, short_archi); -#endif info->version=driver.info_3->cversion; - init_unistr( &info->name, driver.info_3->name ); - init_unistr( &info->architecture, architecture ); - - snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "%s%s", where, driver.info_3->driverpath); + init_unistr( &info->name, driver.info_3->name ); + init_unistr( &info->architecture, driver.info_3->environment ); + + snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "\\\\%s%s", servername, driver.info_3->driverpath); init_unistr( &info->driverpath, temp_driverpath ); - - snprintf(temp_datafile, sizeof(temp_datafile)-1, "%s%s", where, driver.info_3->datafile); + + snprintf(temp_datafile, sizeof(temp_datafile)-1, "\\\\%s%s", servername, driver.info_3->datafile); init_unistr( &info->datafile, temp_datafile ); - - snprintf(temp_configfile, sizeof(temp_configfile)-1, "%s%s", where, driver.info_3->configfile); + + snprintf(temp_configfile, sizeof(temp_configfile)-1, "\\\\%s%s", servername, driver.info_3->configfile); init_unistr( &info->configfile, temp_configfile ); - - snprintf(temp_helpfile, sizeof(temp_helpfile)-1, "%s%s", where, driver.info_3->helpfile); + + snprintf(temp_helpfile, sizeof(temp_helpfile)-1, "\\\\%s%s", servername, driver.info_3->helpfile); init_unistr( &info->helpfile, temp_helpfile ); init_unistr( &info->monitorname, driver.info_3->monitorname ); init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype ); info->dependentfiles=NULL; - init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, where); + init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, servername); } /******************************************************************** * construct_printer_info_3 * fill a printer_info_3 struct ********************************************************************/ -static void construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, - fstring servername, fstring architecture) +static uint32 construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, fstring servername, fstring architecture, uint32 version) { NT_PRINTER_INFO_LEVEL *printer = NULL; NT_PRINTER_DRIVER_INFO_LEVEL driver; - +uint32 status=0; ZERO_STRUCT(driver); - get_a_printer(&printer, 2, lp_servicename(snum) ); - get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture); + status=get_a_printer(&printer, 2, lp_servicename(snum) ); + DEBUG(8,("construct_printer_driver_info_3: status: %d\n", status)); + if (status != 0) + return ERROR_INVALID_PRINTER_NAME; + + status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version); + DEBUG(8,("construct_printer_driver_info_3: status: %d\n", status)); + if (status != 0) + return ERROR_UNKNOWN_PRINTER_DRIVER; - fill_printer_driver_info_3(info, driver, servername, architecture); + fill_printer_driver_info_3(info, driver, servername); free_a_printer(&printer,2); + + return NT_STATUS_NO_PROBLEMO; } /**************************************************************************** @@ -2678,14 +2668,19 @@ static void free_printer_driver_info_3(DRIVER_INFO_3 *info) /**************************************************************************** ****************************************************************************/ -static uint32 getprinterdriver2_level1(fstring servername, fstring architecture, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +static uint32 getprinterdriver2_level1(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) { DRIVER_INFO_1 *info=NULL; + uint32 status; if((info=(DRIVER_INFO_1 *)malloc(sizeof(DRIVER_INFO_1))) == NULL) return ERROR_NOT_ENOUGH_MEMORY; - construct_printer_driver_info_1(info, snum, servername, architecture); + status=construct_printer_driver_info_1(info, snum, servername, architecture, version); + if (status != NT_STATUS_NO_PROBLEMO) { + safe_free(info); + return status; + } /* check the required size. */ *needed += spoolss_size_printer_driver_info_1(info); @@ -2709,14 +2704,19 @@ static uint32 getprinterdriver2_level1(fstring servername, fstring architecture, /**************************************************************************** ****************************************************************************/ -static uint32 getprinterdriver2_level2(fstring servername, fstring architecture, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +static uint32 getprinterdriver2_level2(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) { DRIVER_INFO_2 *info=NULL; + uint32 status; if((info=(DRIVER_INFO_2 *)malloc(sizeof(DRIVER_INFO_2))) == NULL) return ERROR_NOT_ENOUGH_MEMORY; - construct_printer_driver_info_2(info, snum, servername, architecture); + status=construct_printer_driver_info_2(info, snum, servername, architecture, version); + if (status != NT_STATUS_NO_PROBLEMO) { + safe_free(info); + return status; + } /* check the required size. */ *needed += spoolss_size_printer_driver_info_2(info); @@ -2740,13 +2740,17 @@ static uint32 getprinterdriver2_level2(fstring servername, fstring architecture, /**************************************************************************** ****************************************************************************/ -static uint32 getprinterdriver2_level3(fstring servername, fstring architecture, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +static uint32 getprinterdriver2_level3(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) { DRIVER_INFO_3 info; + uint32 status; ZERO_STRUCT(info); - construct_printer_driver_info_3(&info, snum, servername, architecture); + status=construct_printer_driver_info_3(&info, snum, servername, architecture, version); + if (status != NT_STATUS_NO_PROBLEMO) { + return status; + } /* check the required size. */ *needed += spoolss_size_printer_driver_info_3(&info); @@ -2792,13 +2796,13 @@ uint32 _spoolss_getprinterdriver2(POLICY_HND *handle, const UNISTR2 *uni_arch, u switch (level) { case 1: - return getprinterdriver2_level1(servername, architecture, snum, buffer, offered, needed); + return getprinterdriver2_level1(servername, architecture, clientmajorversion, snum, buffer, offered, needed); break; case 2: - return getprinterdriver2_level2(servername, architecture, snum, buffer, offered, needed); + return getprinterdriver2_level2(servername, architecture, clientmajorversion, snum, buffer, offered, needed); break; case 3: - return getprinterdriver2_level3(servername, architecture, snum, buffer, offered, needed); + return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed); break; default: return ERROR_INVALID_LEVEL; @@ -3113,7 +3117,7 @@ static uint32 update_printer(POLICY_HND *handle, uint32 level, /* Check calling user has permission to update printer description */ -#if 1 /* JFMTEST */ +#if 0 /* JFMTEST */ if (!nt_printing_getsec(Printer->dev.handlename, &sd)) { DEBUG(3, ("Could not get security descriptor for printer %s", Printer->dev.handlename)); @@ -3543,24 +3547,46 @@ uint32 _spoolss_setjob( POLICY_HND *handle, /**************************************************************************** Enumerates all printer drivers at level 1. ****************************************************************************/ -static uint32 enumprinterdrivers_level1(fstring *list, fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static uint32 enumprinterdrivers_level1(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { int i; + int ndrivers; + uint32 version; + fstring *list = NULL; + NT_PRINTER_DRIVER_INFO_LEVEL driver; DRIVER_INFO_1 *driver_info_1=NULL; - ZERO_STRUCT(driver); + *returned=0; - if((driver_info_1=(DRIVER_INFO_1 *)malloc(*returned * sizeof(DRIVER_INFO_1))) == NULL) - return ERROR_NOT_ENOUGH_MEMORY; +#define MAX_VERSION 4 - for (i=0; i<*returned; i++) { - get_a_printer_driver(&driver, 3, list[i], architecture); - fill_printer_driver_info_1(&(driver_info_1[i]), driver, servername, architecture ); + for (version=0; version<MAX_VERSION; version++) { + list=NULL; + ndrivers=get_ntdrivers(&list, architecture, version); + DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version)); + + if(ndrivers == -1) + return ERROR_NOT_ENOUGH_MEMORY; + + if(ndrivers != 0) { + if((driver_info_1=(DRIVER_INFO_1 *)Realloc(driver_info_1, (*returned+ndrivers) * sizeof(DRIVER_INFO_1))) == NULL) { + safe_free(list); + return ERROR_NOT_ENOUGH_MEMORY; + } + } + + for (i=0; i<ndrivers; i++) { + DEBUGADD(5,("\tdriver: [%s]\n", list[i])); + ZERO_STRUCT(driver); + get_a_printer_driver(&driver, 3, list[i], architecture, version); + fill_printer_driver_info_1(&(driver_info_1[*returned+i]), driver, servername, architecture ); + } + + *returned+=ndrivers; + safe_free(list); } - safe_free(list); - /* check the required size. */ for (i=0; i<*returned; i++) { DEBUGADD(6,("adding driver [%d]'s size\n",i)); @@ -3591,28 +3617,46 @@ static uint32 enumprinterdrivers_level1(fstring *list, fstring servername, fstri /**************************************************************************** Enumerates all printer drivers at level 2. ****************************************************************************/ -static uint32 enumprinterdrivers_level2(fstring *list, fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static uint32 enumprinterdrivers_level2(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { int i; + int ndrivers; + uint32 version; + fstring *list = NULL; + + NT_PRINTER_DRIVER_INFO_LEVEL driver; DRIVER_INFO_2 *driver_info_2=NULL; - if (*returned > 0 && - !(driver_info_2=(DRIVER_INFO_2 *)malloc(*returned * sizeof(DRIVER_INFO_2)))) - return ERROR_NOT_ENOUGH_MEMORY; + *returned=0; - for (i=0; i<*returned; i++) { - NT_PRINTER_DRIVER_INFO_LEVEL driver; - ZERO_STRUCT(driver); - if (get_a_printer_driver(&driver, 3, list[i], architecture) - != 0) { - *returned = i; - break; +#define MAX_VERSION 4 + + for (version=0; version<MAX_VERSION; version++) { + list=NULL; + ndrivers=get_ntdrivers(&list, architecture, version); + DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version)); + + if(ndrivers == -1) + return ERROR_NOT_ENOUGH_MEMORY; + + if(ndrivers != 0) { + if((driver_info_2=(DRIVER_INFO_2 *)Realloc(driver_info_2, (*returned+ndrivers) * sizeof(DRIVER_INFO_2))) == NULL) { + safe_free(list); + return ERROR_NOT_ENOUGH_MEMORY; + } } - fill_printer_driver_info_2(&(driver_info_2[i]), driver, servername, architecture ); + + for (i=0; i<ndrivers; i++) { + DEBUGADD(5,("\tdriver: [%s]\n", list[i])); + ZERO_STRUCT(driver); + get_a_printer_driver(&driver, 3, list[i], architecture, version); + fill_printer_driver_info_2(&(driver_info_2[*returned+i]), driver, servername); + } + + *returned+=ndrivers; + safe_free(list); } - safe_free(list); - /* check the required size. */ for (i=0; i<*returned; i++) { DEBUGADD(6,("adding driver [%d]'s size\n",i)); @@ -3643,24 +3687,46 @@ static uint32 enumprinterdrivers_level2(fstring *list, fstring servername, fstri /**************************************************************************** Enumerates all printer drivers at level 3. ****************************************************************************/ -static uint32 enumprinterdrivers_level3(fstring *list, fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static uint32 enumprinterdrivers_level3(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { int i; + int ndrivers; + uint32 version; + fstring *list = NULL; + NT_PRINTER_DRIVER_INFO_LEVEL driver; DRIVER_INFO_3 *driver_info_3=NULL; - ZERO_STRUCT(driver); + *returned=0; - if((driver_info_3=(DRIVER_INFO_3 *)malloc((*returned)*sizeof(DRIVER_INFO_3))) == NULL) - return ERROR_NOT_ENOUGH_MEMORY; +#define MAX_VERSION 4 - for (i=0; i<*returned; i++) { - get_a_printer_driver(&driver, 3, list[i], architecture); - fill_printer_driver_info_3(&(driver_info_3[i]), driver, servername, architecture ); + for (version=0; version<MAX_VERSION; version++) { + list=NULL; + ndrivers=get_ntdrivers(&list, architecture, version); + DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version)); + + if(ndrivers == -1) + return ERROR_NOT_ENOUGH_MEMORY; + + if(ndrivers != 0) { + if((driver_info_3=(DRIVER_INFO_3 *)Realloc(driver_info_3, (*returned+ndrivers) * sizeof(DRIVER_INFO_3))) == NULL) { + safe_free(list); + return ERROR_NOT_ENOUGH_MEMORY; + } + } + + for (i=0; i<ndrivers; i++) { + DEBUGADD(5,("\tdriver: [%s]\n", list[i])); + ZERO_STRUCT(driver); + get_a_printer_driver(&driver, 3, list[i], architecture, version); + fill_printer_driver_info_3(&(driver_info_3[*returned+i]), driver, servername); + } + + *returned+=ndrivers; + safe_free(list); } - - safe_free(list); - + /* check the required size. */ for (i=0; i<*returned; i++) { DEBUGADD(6,("adding driver [%d]'s size\n",i)); @@ -3709,27 +3775,20 @@ uint32 _spoolss_enumprinterdrivers( UNISTR2 *name, UNISTR2 *environment, uint32 *returned=0; unistr2_to_ascii(architecture, environment, sizeof(architecture)-1); - *returned=get_ntdrivers(&list, architecture); - DEBUGADD(4,("we have: [%d] drivers in environment [%s]\n", *returned, architecture)); - if(*returned == -1) - return ERROR_NOT_ENOUGH_MEMORY; - - for (i=0; i<*returned; i++) - DEBUGADD(5,("driver: [%s]\n", list[i])); - switch (level) { case 1: - return enumprinterdrivers_level1(list, servername, architecture, buffer, offered, needed, returned); + return enumprinterdrivers_level1(servername, architecture, buffer, offered, needed, returned); break; case 2: - return enumprinterdrivers_level2(list, servername, architecture, buffer, offered, needed, returned); + return enumprinterdrivers_level2(servername, architecture, buffer, offered, needed, returned); break; case 3: - return enumprinterdrivers_level3(list, servername, architecture, buffer, offered, needed, returned); + return enumprinterdrivers_level3(servername, architecture, buffer, offered, needed, returned); break; default: *returned=0; + safe_free(list); return ERROR_INVALID_LEVEL; break; } @@ -4094,77 +4153,34 @@ uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_name, uint32 level, } /**************************************************************************** - Modify internal driver heirarchy. -****************************************************************************/ - -#if MANGLE_DRIVER_PATH -static uint32 modify_driver_heirarchy(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level) -{ - pstring path_old; - pstring path_new; - pstring short_archi; - pstring model_name; - - /* find_service is an smbd-specific function call */ - int snum = find_service("print$"); - char *model = NULL; - - *short_archi = '\0'; - switch (level) { - case 3: - get_short_archi(short_archi, driver->info_3->environment); - model = driver->info_3->name; - break; - case 6: - get_short_archi(short_archi, driver->info_6->environment); - model = driver->info_6->name; - break; - default: - DEBUG(0,("modify_driver_heirarchy: unknown info level (%d)\n", level)); - return ERROR_INVALID_LEVEL; - break; - } - - slprintf(path_old, sizeof(path_old)-1, "%s/%s/TMP_%s", lp_pathname(snum), short_archi, - client_addr()); - - /* Clean up any '/' and other characters in the model name. */ - alpha_strcpy(model_name, model, sizeof(pstring)); - - slprintf(path_new, sizeof(path_new)-1, "%s/%s/%s", lp_pathname(snum), short_archi, model_name); - - DEBUG(10,("modify_driver_heirarchy: old_path=%s, new_path=%s\n", - path_old, path_new )); - if (dos_rename(path_old, path_new) == -1) { - DEBUG(0,("modify_driver_heirarchy: rename from %s to %s failed (%s)\n", - path_old, path_new, strerror(errno) )); - /* We need to clean up here.... - how ? */ - return ERROR_ACCESS_DENIED; /* We need a generic mapping from NT errors here... */ - } - - return NT_STATUS_NO_PROBLEMO; -} -#endif - -/**************************************************************************** ****************************************************************************/ -uint32 _spoolss_addprinterdriver( const UNISTR2 *server_name, - uint32 level, - const SPOOL_PRINTER_DRIVER_INFO_LEVEL *info) +uint32 _spoolss_addprinterdriver(pipes_struct *p, const UNISTR2 *server_name, + uint32 level, const SPOOL_PRINTER_DRIVER_INFO_LEVEL *info) { uint32 err = NT_STATUS_NO_PROBLEMO; NT_PRINTER_DRIVER_INFO_LEVEL driver; + struct current_user user; + ZERO_STRUCT(driver); + if (p->ntlmssp_auth_validated) { + memcpy(&user, &p->pipe_user, sizeof(user)); + } else { + extern struct current_user current_user; + memcpy(&user, ¤t_user, sizeof(user)); + } + convert_printer_driver_info(info, &driver, level); + DEBUG(5,("Cleaning driver's information\n")); + clean_up_driver_struct(driver, level); + + DEBUG(5,("Moving driver to final destination\n")); + move_driver_to_download_area(driver, level, &user); + if (add_a_printer_driver(driver, level)!=0) return ERROR_ACCESS_DENIED; -#if MANGLE_DRIVER_PATH - err = modify_driver_heirarchy(&driver, level); -#endif - free_a_printer_driver(driver, level); return err; @@ -4185,20 +4201,17 @@ static uint32 getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environmen pstring long_archi; pstring short_archi; DRIVER_DIRECTORY_1 *info=NULL; - + + unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1); + + if (get_short_archi(short_archi, long_archi)==FALSE) + return ERROR_INVALID_ENVIRONMENT; + if((info=(DRIVER_DIRECTORY_1 *)malloc(sizeof(DRIVER_DIRECTORY_1))) == NULL) return ERROR_NOT_ENOUGH_MEMORY; - - unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1); - get_short_archi(short_archi, long_archi); - -#if MANGLE_DRIVER_PATH - slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s\\TMP_%s", global_myname, short_archi, - client_addr()); -#else - slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", - global_myname, short_archi); -#endif + + slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", global_myname, short_archi); + DEBUG(4,("printer driver directory: [%s]\n", path)); fill_driverdir_1(info, path); diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index 2f338cdb22..3a80e5d0e7 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -470,7 +470,7 @@ uint32 cmd_spoolss_getprinterdriverdir(struct client_info *info, int argc, char fstrcpy(env, argv[1]); - for (i=2; i<argc; i++) { + for (i=2; i<=argc; i++) { fstrcat(env, " "); fstrcat(env, argv[i]); } diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 00a0ce3c4a..19af1fdc3d 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -3101,15 +3101,14 @@ int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_ /**************************************************************************** - reply to a mkdir + The guts of the mkdir command, split out so it may be called by the NT SMB + code. ****************************************************************************/ -int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +int mkdir_internal(connection_struct *conn, char *inbuf, char *outbuf, pstring directory) { - pstring directory; - int outsize,ret= -1; BOOL bad_path = False; - - pstrcpy(directory,smb_buf(inbuf) + 1); + int ret= -1; + unix_convert(directory,conn,0,&bad_path,NULL); if (check_name(directory, conn)) @@ -3125,10 +3124,23 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, } return(UNIXERROR(ERRDOS,ERRnoaccess)); } +} - outsize = set_message(outbuf,0,0,True); +/**************************************************************************** + reply to a mkdir +****************************************************************************/ +int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize) +{ + pstring directory; + int outsize; + + pstrcpy(directory,smb_buf(inbuf) + 1); + + outsize=mkdir_internal(conn, inbuf, outbuf, directory); + if(outsize == 0) + outsize = set_message(outbuf,0,0,True); - DEBUG( 3, ( "mkdir %s ret=%d\n", directory, ret ) ); + DEBUG( 3, ( "mkdir %s ret=%d\n", directory, outsize ) ); return(outsize); } |