*/
#include "includes.h"
+#include "librpc/gen_ndr/messaging.h"
+#include "printing/pcap.h"
+#include "registry.h"
+#include "registry/reg_objects.h"
+#include "../librpc/gen_ndr/ndr_security.h"
static TDB_CONTEXT *tdb_forms; /* used for forms files */
static TDB_CONTEXT *tdb_drivers; /* used for driver files */
#define FORMS_PREFIX "FORMS/"
#define DRIVERS_PREFIX "DRIVERS/"
-#define DRIVER_INIT_PREFIX "DRIVER_INIT/"
#define PRINTERS_PREFIX "PRINTERS/"
#define SECDESC_PREFIX "SECDESC/"
#define GLOBAL_C_SETPRINTER "GLOBALS/c_setprinter"
{"Legal",0x1,0x34b5c,0x56d10,0x0,0x0,0x34b5c,0x56d10},
{"Statement",0x1,0x221b4,0x34b5c,0x0,0x0,0x221b4,0x34b5c},
{"Executive",0x1,0x2cf56,0x411cc,0x0,0x0,0x2cf56,0x411cc},
+ {"A0",0x1,0xcd528,0x122488,0x0,0x0,0xcd528,0x122488},
+ {"A1",0x1,0x91050,0xcd528,0x0,0x0,0x91050,0xcd528},
{"A3",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
{"A4",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
{"A4 Small",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
{"PRC Envelope #10 Rotated",0x1,0x6fd10,0x4f1a0,0x0,0x0,0x6fd10,0x4f1a0}
};
-struct table_node {
- const char *long_archi;
- const char *short_archi;
- int version;
-};
-
-#define SPL_ARCH_WIN40 "WIN40"
-#define SPL_ARCH_W32X86 "W32X86"
-#define SPL_ARCH_W32MIPS "W32MIPS"
-#define SPL_ARCH_W32ALPHA "W32ALPHA"
-#define SPL_ARCH_W32PPC "W32PPC"
-#define SPL_ARCH_IA64 "IA64"
-#define SPL_ARCH_X64 "x64"
-
-static const struct table_node archi_table[]= {
+static const struct print_architecture_table_node archi_table[]= {
{"Windows 4.0", SPL_ARCH_WIN40, 0 },
{"Windows NT x86", SPL_ARCH_W32X86, 2 },
TDB_DATA data, void *state )
{
NTSTATUS status;
- SEC_DESC_BUF *sd_orig = NULL;
- SEC_DESC_BUF *sd_new, *sd_store;
- SEC_DESC *sec, *new_sec;
+ struct sec_desc_buf *sd_orig = NULL;
+ struct sec_desc_buf *sd_new, *sd_store;
+ struct security_descriptor *sec, *new_sec;
TALLOC_CTX *ctx = state;
int result, i;
uint32 sd_size;
}
}
- /* create a new SEC_DESC with the appropriate owner and group SIDs */
+ /* create a new struct security_descriptor with the appropriate owner and group SIDs */
- new_sec = make_sec_desc( ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
+ new_sec = make_sec_desc( ctx, SD_REVISION, SEC_DESC_SELF_RELATIVE,
&global_sid_Builtin_Administrators,
&global_sid_Builtin_Administrators,
NULL, NULL, &size_new_sec );
return 0;
}
- if ( !(sd_store = sec_desc_merge( ctx, sd_new, sd_orig )) ) {
+ if ( !(sd_store = sec_desc_merge_buf( ctx, sd_new, sd_orig )) ) {
DEBUG(0,("sec_desc_upg_fn: Failed to update sec_desc for %s\n", key.dptr ));
return 0;
}
/* store it back */
- sd_size = ndr_size_security_descriptor(sd_store->sd, NULL, 0)
- + sizeof(SEC_DESC_BUF);
+ sd_size = ndr_size_security_descriptor(sd_store->sd, 0)
+ + sizeof(struct sec_desc_buf);
status = marshall_sec_desc_buf(ctx, sd_store, &data.dptr, &data.dsize);
if (!NT_STATUS_IS_OK(status)) {
messaging_register(msg_ctx, NULL, MSG_PRINTER_DRVUPGRADE,
do_drv_upgrade_printer);
- /*
- * register callback to handle updating printer data
- * when a driver is initialized
- */
-
- messaging_register(msg_ctx, NULL, MSG_PRINTERDATA_INIT_RESET,
- reset_all_printerdata);
-
/* of course, none of the message callbacks matter if you don't
tell messages.c that you interested in receiving PRINT_GENERAL
- msgs. This is done in claim_connection() */
+ msgs. This is done in serverid_register() */
if ( lp_security() == SEC_ADS ) {
Function to allow filename parsing "the old way".
********************************************************************/
-static char *driver_unix_convert(connection_struct *conn,
- const char *old_name,
- SMB_STRUCT_STAT *pst)
+static NTSTATUS driver_unix_convert(connection_struct *conn,
+ const char *old_name,
+ struct smb_filename **smb_fname)
{
+ NTSTATUS status;
TALLOC_CTX *ctx = talloc_tos();
char *name = talloc_strdup(ctx, old_name);
- char *new_name = NULL;
if (!name) {
- return NULL;
+ return NT_STATUS_NO_MEMORY;
}
unix_format(name);
name = unix_clean_name(ctx, name);
if (!name) {
- return NULL;
+ return NT_STATUS_NO_MEMORY;
}
trim_string(name,"/","/");
- unix_convert(ctx,conn, name, false, &new_name, NULL, pst);
- return new_name;
+
+ status = unix_convert(ctx, conn, name, smb_fname, 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ return NT_STATUS_OK;
}
/*******************************************************************
if (!*list) {
return 0;
}
- return sizeof(default_forms) / sizeof(default_forms[0]);
+ return ARRAY_SIZE(default_forms);
}
/****************************************************************************
bool get_a_builtin_ntform_by_string(const char *form_name, nt_forms_struct *form)
{
- int i,count;
+ int i;
DEBUGADD(6,("Looking for builtin form %s \n", form_name));
- count = sizeof(default_forms) / sizeof(default_forms[0]);
- for (i=0;i<count;i++) {
+ for (i=0; i<ARRAY_SIZE(default_forms); i++) {
if (strequal(form_name,default_forms[i].name)) {
DEBUGADD(6,("Found builtin form %s \n", form_name));
memcpy(form,&default_forms[i],sizeof(*form));
- break;
+ return true;
}
}
- return (i !=count);
+ return false;
}
/****************************************************************************
if (n == *count) {
DEBUG(10,("delete_a_form, [%s] not found\n", del_name));
- *ret = WERR_INVALID_PARAM;
+ *ret = WERR_INVALID_FORM_NAME;
return False;
}
static int file_version_is_newer(connection_struct *conn, fstring new_file, fstring old_file)
{
bool use_version = true;
- char *filepath = NULL;
uint32 new_major;
uint32 new_minor;
uint32 old_minor;
time_t old_create_time;
+ struct smb_filename *smb_fname = NULL;
files_struct *fsp = NULL;
SMB_STRUCT_STAT st;
- SMB_STRUCT_STAT stat_buf;
NTSTATUS status;
+ int ret;
SET_STAT_INVALID(st);
- SET_STAT_INVALID(stat_buf);
new_create_time = (time_t)0;
old_create_time = (time_t)0;
/* Get file version info (if available) for previous file (if it exists) */
- filepath = driver_unix_convert(conn,old_file,&stat_buf);
- if (!filepath) {
+ status = driver_unix_convert(conn, old_file, &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
goto error_exit;
}
conn, /* conn */
NULL, /* req */
0, /* root_dir_fid */
- filepath, /* fname */
- 0, /* create_file_flags */
+ smb_fname, /* fname */
FILE_GENERIC_READ, /* access_mask */
FILE_SHARE_READ | FILE_SHARE_WRITE, /* share_access */
FILE_OPEN, /* create_disposition*/
FILE_ATTRIBUTE_NORMAL, /* file_attributes */
INTERNAL_OPEN_ONLY, /* oplock_request */
0, /* allocation_size */
+ 0, /* private_flags */
NULL, /* sd */
NULL, /* ea_list */
&fsp, /* result */
- NULL, /* pinfo */
- &stat_buf); /* psbuf */
+ NULL); /* pinfo */
if (!NT_STATUS_IS_OK(status)) {
/* Old file not found, so by definition new file is in fact newer */
- DEBUG(10,("file_version_is_newer: Can't open old file [%s], errno = %d\n",
- filepath, errno));
- return 1;
+ DEBUG(10,("file_version_is_newer: Can't open old file [%s], "
+ "errno = %d\n", smb_fname_str_dbg(smb_fname),
+ errno));
+ ret = 1;
+ goto done;
} else {
- int ret = get_file_version(fsp, old_file, &old_major, &old_minor);
+ ret = get_file_version(fsp, old_file, &old_major, &old_minor);
if (ret == -1) {
goto error_exit;
}
if (SMB_VFS_FSTAT(fsp, &st) == -1) {
goto error_exit;
}
- old_create_time = st.st_mtime;
+ old_create_time = convert_timespec_to_time_t(st.st_ex_mtime);
DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n",
(long)old_create_time));
}
fsp = NULL;
/* Get file version info (if available) for new file */
- filepath = driver_unix_convert(conn,new_file,&stat_buf);
- if (!filepath) {
+ status = driver_unix_convert(conn, new_file, &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
goto error_exit;
}
conn, /* conn */
NULL, /* req */
0, /* root_dir_fid */
- filepath, /* fname */
- 0, /* create_file_flags */
+ smb_fname, /* fname */
FILE_GENERIC_READ, /* access_mask */
FILE_SHARE_READ | FILE_SHARE_WRITE, /* share_access */
FILE_OPEN, /* create_disposition*/
FILE_ATTRIBUTE_NORMAL, /* file_attributes */
INTERNAL_OPEN_ONLY, /* oplock_request */
0, /* allocation_size */
+ 0, /* private_flags */
NULL, /* sd */
NULL, /* ea_list */
&fsp, /* result */
- NULL, /* pinfo */
- &stat_buf); /* psbuf */
+ NULL); /* pinfo */
if (!NT_STATUS_IS_OK(status)) {
/* New file not found, this shouldn't occur if the caller did its job */
- DEBUG(3,("file_version_is_newer: Can't open new file [%s], errno = %d\n",
- filepath, errno));
+ DEBUG(3,("file_version_is_newer: Can't open new file [%s], "
+ "errno = %d\n", smb_fname_str_dbg(smb_fname), errno));
goto error_exit;
} else {
- int ret = get_file_version(fsp, new_file, &new_major, &new_minor);
+ ret = get_file_version(fsp, new_file, &new_major, &new_minor);
if (ret == -1) {
goto error_exit;
}
if (SMB_VFS_FSTAT(fsp, &st) == -1) {
goto error_exit;
}
- new_create_time = st.st_mtime;
+ new_create_time = convert_timespec_to_time_t(st.st_ex_mtime);
DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n",
(long)new_create_time));
}
(new_major == old_major && new_minor > old_minor)) {
DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
- return 1;
+ ret = 1;
+ goto done;
}
else {
DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
- return 0;
+ ret = 0;
+ goto done;
}
} else {
/* Compare modification time/dates and choose the newest time/date */
if (new_create_time > old_create_time) {
DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
- return 1;
+ ret = 1;
+ goto done;
}
else {
DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
- return 0;
+ ret = 0;
+ goto done;
}
}
- error_exit:
- if(fsp)
- close_file(NULL, fsp, NORMAL_CLOSE);
- return -1;
+ error_exit:
+ if(fsp)
+ close_file(NULL, fsp, NORMAL_CLOSE);
+ ret = -1;
+ done:
+ TALLOC_FREE(smb_fname);
+ return ret;
}
/****************************************************************************
****************************************************************************/
static uint32 get_correct_cversion(struct pipes_struct *p,
const char *architecture,
- fstring driverpath_in,
+ const char *driverpath_in,
WERROR *perr)
{
int cversion;
NTSTATUS nt_status;
- char *driverpath = NULL;
+ struct smb_filename *smb_fname = NULL;
+ char *driverpath = NULL;
files_struct *fsp = NULL;
- SMB_STRUCT_STAT st;
connection_struct *conn = NULL;
NTSTATUS status;
char *oldcwd;
fstring printdollar;
int printdollar_snum;
- SET_STAT_INVALID(st);
-
*perr = WERR_INVALID_PARAM;
/* If architecture is Windows 95/98/ME, the version is always 0. */
goto error_exit;
}
- driverpath = driver_unix_convert(conn,driverpath,&st);
- if (!driverpath) {
- *perr = WERR_NOMEM;
+ nt_status = driver_unix_convert(conn, driverpath, &smb_fname);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ *perr = ntstatus_to_werror(nt_status);
goto error_exit;
}
- if (!vfs_file_exist(conn, driverpath, &st)) {
+ nt_status = vfs_file_exist(conn, smb_fname);
+ if (!NT_STATUS_IS_OK(nt_status)) {
*perr = WERR_BADFILE;
goto error_exit;
}
conn, /* conn */
NULL, /* req */
0, /* root_dir_fid */
- driverpath, /* fname */
- 0, /* create_file_flags */
+ smb_fname, /* fname */
FILE_GENERIC_READ, /* access_mask */
FILE_SHARE_READ | FILE_SHARE_WRITE, /* share_access */
FILE_OPEN, /* create_disposition*/
0, /* create_options */
FILE_ATTRIBUTE_NORMAL, /* file_attributes */
INTERNAL_OPEN_ONLY, /* oplock_request */
+ 0, /* private_flags */
0, /* allocation_size */
NULL, /* sd */
NULL, /* ea_list */
&fsp, /* result */
- NULL, /* pinfo */
- &st); /* psbuf */
+ NULL); /* pinfo */
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
- driverpath, errno));
+ DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = "
+ "%d\n", smb_fname_str_dbg(smb_fname), errno));
*perr = WERR_ACCESS_DENIED;
goto error_exit;
} else {
uint32 major;
uint32 minor;
- int ret = get_file_version(fsp, driverpath, &major, &minor);
+ int ret;
+
+ ret = get_file_version(fsp, smb_fname->base_name, &major, &minor);
if (ret == -1) goto error_exit;
if (!ret) {
- DEBUG(6,("get_correct_cversion: Version info not found [%s]\n", driverpath));
+ DEBUG(6,("get_correct_cversion: Version info not "
+ "found [%s]\n",
+ smb_fname_str_dbg(smb_fname)));
goto error_exit;
}
break;
default:
- DEBUG(6,("get_correct_cversion: cversion invalid [%s] cversion = %d\n",
- driverpath, cversion));
+ DEBUG(6,("get_correct_cversion: cversion "
+ "invalid [%s] cversion = %d\n",
+ smb_fname_str_dbg(smb_fname),
+ cversion));
goto error_exit;
}
- DEBUG(10,("get_correct_cversion: Version info found [%s] major = 0x%x minor = 0x%x\n",
- driverpath, major, minor));
+ DEBUG(10,("get_correct_cversion: Version info found [%s] major"
+ " = 0x%x minor = 0x%x\n",
+ smb_fname_str_dbg(smb_fname), major, minor));
}
DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
- driverpath, cversion));
+ smb_fname_str_dbg(smb_fname), cversion));
goto done;
error_exit:
cversion = -1;
done:
+ TALLOC_FREE(smb_fname);
if (fsp != NULL) {
close_file(NULL, fsp, NORMAL_CLOSE);
}
if (conn != NULL) {
vfs_ChDir(conn, oldcwd);
- conn_free_internal(conn);
+ conn_free(conn);
}
if (cversion != -1) {
*perr = WERR_OK;
/****************************************************************************
****************************************************************************/
-static WERROR clean_up_driver_struct_level_3(struct pipes_struct *rpc_pipe,
- NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
+
+#define strip_driver_path(_mem_ctx, _element) do { \
+ if (_element && ((_p = strrchr((_element), '\\')) != NULL)) { \
+ (_element) = talloc_asprintf((_mem_ctx), "%s", _p+1); \
+ W_ERROR_HAVE_NO_MEMORY((_element)); \
+ } \
+} while (0);
+
+static WERROR clean_up_driver_struct_level(TALLOC_CTX *mem_ctx,
+ struct pipes_struct *rpc_pipe,
+ const char *architecture,
+ const char **driver_path,
+ const char **data_file,
+ const char **config_file,
+ const char **help_file,
+ struct spoolss_StringArray *dependent_files,
+ uint32_t *version)
{
- const char *architecture;
- fstring new_name;
- char *p;
+ const char *short_architecture;
int i;
WERROR err;
+ char *_p;
+
+ if (!*driver_path || !*data_file || !*config_file) {
+ return WERR_INVALID_PARAM;
+ }
/* 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);
+ strip_driver_path(mem_ctx, *driver_path);
+ strip_driver_path(mem_ctx, *data_file);
+ strip_driver_path(mem_ctx, *config_file);
+ if (help_file) {
+ strip_driver_path(mem_ctx, *help_file);
}
- 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);
- }
+ if (dependent_files && dependent_files->string) {
+ for (i=0; dependent_files->string[i]; i++) {
+ strip_driver_path(mem_ctx, dependent_files->string[i]);
}
}
- architecture = get_short_archi(driver->environment);
- if (!architecture) {
+ short_architecture = get_short_archi(architecture);
+ if (!short_architecture) {
return WERR_UNKNOWN_PRINTER_DRIVER;
}
* NT 4: cversion=2
* NT2K: cversion=3
*/
- if ((driver->cversion = get_correct_cversion(rpc_pipe, architecture,
- driver->driverpath,
- &err)) == -1)
+
+ *version = get_correct_cversion(rpc_pipe, short_architecture,
+ *driver_path, &err);
+ if (*version == -1) {
return err;
+ }
return WERR_OK;
}
/****************************************************************************
****************************************************************************/
-static WERROR clean_up_driver_struct_level_6(struct pipes_struct *rpc_pipe,
- NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
-{
- const char *architecture;
- fstring new_name;
- char *p;
- int i;
- WERROR err;
-
- /* 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);
- }
- }
- }
- architecture = get_short_archi(driver->environment);
- if (!architecture) {
- return WERR_UNKNOWN_PRINTER_DRIVER;
+WERROR clean_up_driver_struct(struct pipes_struct *rpc_pipe,
+ struct spoolss_AddDriverInfoCtr *r)
+{
+ switch (r->level) {
+ case 3:
+ return clean_up_driver_struct_level(r, rpc_pipe,
+ r->info.info3->architecture,
+ &r->info.info3->driver_path,
+ &r->info.info3->data_file,
+ &r->info.info3->config_file,
+ &r->info.info3->help_file,
+ r->info.info3->dependent_files,
+ &r->info.info3->version);
+ case 6:
+ return clean_up_driver_struct_level(r, rpc_pipe,
+ r->info.info6->architecture,
+ &r->info.info6->driver_path,
+ &r->info.info6->data_file,
+ &r->info.info6->config_file,
+ &r->info.info6->help_file,
+ r->info.info6->dependent_files,
+ &r->info.info6->version);
+ default:
+ return WERR_NOT_SUPPORTED;
}
+}
- /* 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
- */
-
- if ((driver->version = get_correct_cversion(rpc_pipe, architecture,
- driver->driverpath,
- &err)) == -1)
- return err;
+/****************************************************************************
+ This function sucks and should be replaced. JRA.
+****************************************************************************/
- return WERR_OK;
+static void convert_level_6_to_level3(struct spoolss_AddDriverInfo3 *dst,
+ const struct spoolss_AddDriverInfo6 *src)
+{
+ dst->version = src->version;
+
+ dst->driver_name = src->driver_name;
+ dst->architecture = src->architecture;
+ dst->driver_path = src->driver_path;
+ dst->data_file = src->data_file;
+ dst->config_file = src->config_file;
+ dst->help_file = src->help_file;
+ dst->monitor_name = src->monitor_name;
+ dst->default_datatype = src->default_datatype;
+ dst->_ndr_size_dependent_files = src->_ndr_size_dependent_files;
+ dst->dependent_files = src->dependent_files;
}
/****************************************************************************
+ This function sucks and should be replaced. JRA.
****************************************************************************/
-WERROR clean_up_driver_struct(struct pipes_struct *rpc_pipe,
- NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
- uint32 level)
+
+static void convert_level_8_to_level3(TALLOC_CTX *mem_ctx,
+ struct spoolss_AddDriverInfo3 *dst,
+ const struct spoolss_DriverInfo8 *src)
{
- switch (level) {
- case 3:
- {
- NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
- driver=driver_abstract.info_3;
- return clean_up_driver_struct_level_3(rpc_pipe,
- driver);
- }
- case 6:
- {
- NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver;
- driver=driver_abstract.info_6;
- return clean_up_driver_struct_level_6(rpc_pipe,
- driver);
- }
- default:
- return WERR_INVALID_PARAM;
+ dst->version = src->version;
+ dst->driver_name = src->driver_name;
+ dst->architecture = src->architecture;
+ dst->driver_path = src->driver_path;
+ dst->data_file = src->data_file;
+ dst->config_file = src->config_file;
+ dst->help_file = src->help_file;
+ dst->monitor_name = src->monitor_name;
+ dst->default_datatype = src->default_datatype;
+ if (src->dependent_files) {
+ dst->dependent_files = talloc_zero(mem_ctx, struct spoolss_StringArray);
+ if (!dst->dependent_files) return;
+ dst->dependent_files->string = src->dependent_files;
+ } else {
+ dst->dependent_files = NULL;
}
}
/****************************************************************************
- This function sucks and should be replaced. JRA.
****************************************************************************/
-static void convert_level_6_to_level3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dst, NT_PRINTER_DRIVER_INFO_LEVEL_6 *src)
+static WERROR move_driver_file_to_download_area(TALLOC_CTX *mem_ctx,
+ connection_struct *conn,
+ const char *driver_file,
+ const char *short_architecture,
+ uint32_t driver_version,
+ uint32_t version)
{
- dst->cversion = src->version;
-
- fstrcpy( dst->name, src->name);
- fstrcpy( dst->environment, src->environment);
- fstrcpy( dst->driverpath, src->driverpath);
- fstrcpy( dst->datafile, src->datafile);
- fstrcpy( dst->configfile, src->configfile);
- fstrcpy( dst->helpfile, src->helpfile);
- fstrcpy( dst->monitorname, src->monitorname);
- fstrcpy( dst->defaultdatatype, src->defaultdatatype);
- dst->dependentfiles = src->dependentfiles;
-}
+ struct smb_filename *smb_fname_old = NULL;
+ struct smb_filename *smb_fname_new = NULL;
+ char *old_name = NULL;
+ char *new_name = NULL;
+ NTSTATUS status;
+ WERROR ret;
-#if 0 /* Debugging function */
+ old_name = talloc_asprintf(mem_ctx, "%s/%s",
+ short_architecture, driver_file);
+ W_ERROR_HAVE_NO_MEMORY(old_name);
-static char* ffmt(unsigned char *c){
- int i;
- static char ffmt_str[17];
+ new_name = talloc_asprintf(mem_ctx, "%s/%d/%s",
+ short_architecture, driver_version, driver_file);
+ if (new_name == NULL) {
+ TALLOC_FREE(old_name);
+ return WERR_NOMEM;
+ }
+
+ if (version != -1 && (version = file_version_is_newer(conn, old_name, new_name)) > 0) {
+
+ status = driver_unix_convert(conn, old_name, &smb_fname_old);
+ if (!NT_STATUS_IS_OK(status)) {
+ ret = WERR_NOMEM;
+ goto out;
+ }
- for (i=0; i<16; i++) {
- if ((c[i] < ' ') || (c[i] > '~'))
- ffmt_str[i]='.';
- else
- ffmt_str[i]=c[i];
+ /* Setup a synthetic smb_filename struct */
+ smb_fname_new = TALLOC_ZERO_P(mem_ctx, struct smb_filename);
+ if (!smb_fname_new) {
+ ret = WERR_NOMEM;
+ goto out;
+ }
+
+ smb_fname_new->base_name = new_name;
+
+ DEBUG(10,("move_driver_file_to_download_area: copying '%s' to "
+ "'%s'\n", smb_fname_old->base_name,
+ smb_fname_new->base_name));
+
+ status = copy_file(mem_ctx, conn, smb_fname_old, smb_fname_new,
+ OPENX_FILE_EXISTS_TRUNCATE |
+ OPENX_FILE_CREATE_IF_NOT_EXIST,
+ 0, false);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("move_driver_file_to_download_area: Unable "
+ "to rename [%s] to [%s]: %s\n",
+ smb_fname_old->base_name, new_name,
+ nt_errstr(status)));
+ ret = WERR_ACCESS_DENIED;
+ goto out;
+ }
}
- ffmt_str[16]='\0';
- return ffmt_str;
-}
-#endif
+ ret = WERR_OK;
+ out:
+ TALLOC_FREE(smb_fname_old);
+ TALLOC_FREE(smb_fname_new);
+ return ret;
+}
-/****************************************************************************
-****************************************************************************/
WERROR move_driver_to_download_area(struct pipes_struct *p,
- NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
- uint32 level, WERROR *perr)
+ struct spoolss_AddDriverInfoCtr *r,
+ WERROR *perr)
{
- NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
- NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver;
- const char *architecture;
+ struct spoolss_AddDriverInfo3 *driver;
+ struct spoolss_AddDriverInfo3 converted_driver;
+ const char *short_architecture;
+ struct smb_filename *smb_dname = NULL;
char *new_dir = NULL;
- char *old_name = NULL;
- char *new_name = NULL;
connection_struct *conn = NULL;
NTSTATUS nt_status;
- SMB_STRUCT_STAT st;
int i;
TALLOC_CTX *ctx = talloc_tos();
int ver = 0;
*perr = WERR_OK;
- if (level==3)
- driver=driver_abstract.info_3;
- else if (level==6) {
- convert_level_6_to_level3(&converted_driver, driver_abstract.info_6);
+ switch (r->level) {
+ case 3:
+ driver = r->info.info3;
+ break;
+ case 6:
+ convert_level_6_to_level3(&converted_driver, r->info.info6);
driver = &converted_driver;
- } else {
- DEBUG(0,("move_driver_to_download_area: Unknown info level (%u)\n", (unsigned int)level ));
+ break;
+ default:
+ DEBUG(0,("move_driver_to_download_area: Unknown info level (%u)\n", (unsigned int)r->level));
return WERR_UNKNOWN_LEVEL;
}
- architecture = get_short_archi(driver->environment);
- if (!architecture) {
+ short_architecture = get_short_archi(driver->architecture);
+ if (!short_architecture) {
return WERR_UNKNOWN_PRINTER_DRIVER;
}
return *perr;
}
- DEBUG(5,("Creating first directory\n"));
new_dir = talloc_asprintf(ctx,
"%s/%d",
- architecture,
- driver->cversion);
+ short_architecture,
+ driver->version);
if (!new_dir) {
*perr = WERR_NOMEM;
goto err_exit;
}
- new_dir = driver_unix_convert(conn,new_dir,&st);
- if (!new_dir) {
+ nt_status = driver_unix_convert(conn, new_dir, &smb_dname);
+ if (!NT_STATUS_IS_OK(nt_status)) {
*perr = WERR_NOMEM;
goto err_exit;
}
- create_directory(conn, NULL, new_dir);
+ DEBUG(5,("Creating first directory: %s\n", smb_dname->base_name));
+
+ create_directory(conn, NULL, smb_dname);
/* For each driver file, archi\filexxx.yyy, if there is a duplicate file
* listed for this driver which has already been moved, skip it (note:
* drivers may list the same file name several times. Then check if the
- * file already exists in archi\cversion\, if so, check that the version
+ * file already exists in archi\version\, if so, check that the version
* info (or time stamps if version info is unavailable) is newer (or the
- * date is later). If it is, move it to archi\cversion\filexxx.yyy.
+ * date is later). If it is, move it to archi\version\filexxx.yyy.
* Otherwise, delete the file.
*
- * If a file is not moved to archi\cversion\ because of an error, all the
+ * If a file is not moved to archi\version\ because of an error, all the
* rest of the 'unmoved' driver files are removed from archi\. If one or
- * more of the driver's files was already moved to archi\cversion\, it
+ * more of the driver's files was already moved to archi\version\, it
* potentially leaves the driver in a partially updated state. Version
* trauma will most likely occur if an client attempts to use any printer
* bound to the driver. Perhaps a rewrite to make sure the moves can be
DEBUG(5,("Moving files now !\n"));
- if (driver->driverpath && strlen(driver->driverpath)) {
- new_name = talloc_asprintf(ctx,
- "%s/%s",
- architecture,
- driver->driverpath);
- if (!new_name) {
- *perr = WERR_NOMEM;
- goto err_exit;
- }
- old_name = talloc_asprintf(ctx,
- "%s/%s",
- new_dir,
- driver->driverpath);
- if (!old_name) {
- *perr = WERR_NOMEM;
- goto err_exit;
- }
+ if (driver->driver_path && strlen(driver->driver_path)) {
- if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
- new_name = driver_unix_convert(conn,new_name,&st);
- if (!new_name) {
- *perr = WERR_NOMEM;
- goto err_exit;
- }
- if ( !NT_STATUS_IS_OK(copy_file(ctx,conn, new_name, old_name, OPENX_FILE_EXISTS_TRUNCATE|
- OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False))) {
- DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
- new_name, old_name));
- *perr = WERR_ACCESS_DENIED;
+ *perr = move_driver_file_to_download_area(ctx,
+ conn,
+ driver->driver_path,
+ short_architecture,
+ driver->version,
+ ver);
+ if (!W_ERROR_IS_OK(*perr)) {
+ if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
ver = -1;
}
+ goto err_exit;
}
}
- if (driver->datafile && strlen(driver->datafile)) {
- if (!strequal(driver->datafile, driver->driverpath)) {
- new_name = talloc_asprintf(ctx,
- "%s/%s",
- architecture,
- driver->datafile);
- if (!new_name) {
- *perr = WERR_NOMEM;
- goto err_exit;
- }
- old_name = talloc_asprintf(ctx,
- "%s/%s",
- new_dir,
- driver->datafile);
- if (!old_name) {
- *perr = WERR_NOMEM;
- goto err_exit;
- }
- if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
- new_name = driver_unix_convert(conn,new_name,&st);
- if (!new_name) {
- *perr = WERR_NOMEM;
- goto err_exit;
- }
- if ( !NT_STATUS_IS_OK(copy_file(ctx,conn, new_name, old_name, OPENX_FILE_EXISTS_TRUNCATE|
- OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False))) {
- DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
- new_name, old_name));
- *perr = WERR_ACCESS_DENIED;
+ if (driver->data_file && strlen(driver->data_file)) {
+ if (!strequal(driver->data_file, driver->driver_path)) {
+
+ *perr = move_driver_file_to_download_area(ctx,
+ conn,
+ driver->data_file,
+ short_architecture,
+ driver->version,
+ ver);
+ if (!W_ERROR_IS_OK(*perr)) {
+ if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
ver = -1;
}
+ goto err_exit;
}
}
}
- if (driver->configfile && strlen(driver->configfile)) {
- if (!strequal(driver->configfile, driver->driverpath) &&
- !strequal(driver->configfile, driver->datafile)) {
- new_name = talloc_asprintf(ctx,
- "%s/%s",
- architecture,
- driver->configfile);
- if (!new_name) {
- *perr = WERR_NOMEM;
- goto err_exit;
- }
- old_name = talloc_asprintf(ctx,
- "%s/%s",
- new_dir,
- driver->configfile);
- if (!old_name) {
- *perr = WERR_NOMEM;
- goto err_exit;
- }
- if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
- new_name = driver_unix_convert(conn,new_name,&st);
- if (!new_name) {
- *perr = WERR_NOMEM;
- goto err_exit;
- }
- if ( !NT_STATUS_IS_OK(copy_file(ctx,conn, new_name, old_name, OPENX_FILE_EXISTS_TRUNCATE|
- OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False))) {
- DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
- new_name, old_name));
- *perr = WERR_ACCESS_DENIED;
+ if (driver->config_file && strlen(driver->config_file)) {
+ if (!strequal(driver->config_file, driver->driver_path) &&
+ !strequal(driver->config_file, driver->data_file)) {
+
+ *perr = move_driver_file_to_download_area(ctx,
+ conn,
+ driver->config_file,
+ short_architecture,
+ driver->version,
+ ver);
+ if (!W_ERROR_IS_OK(*perr)) {
+ if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
ver = -1;
}
+ goto err_exit;
}
}
}
- if (driver->helpfile && strlen(driver->helpfile)) {
- if (!strequal(driver->helpfile, driver->driverpath) &&
- !strequal(driver->helpfile, driver->datafile) &&
- !strequal(driver->helpfile, driver->configfile)) {
- new_name = talloc_asprintf(ctx,
- "%s/%s",
- architecture,
- driver->helpfile);
- if (!new_name) {
- *perr = WERR_NOMEM;
- goto err_exit;
- }
- old_name = talloc_asprintf(ctx,
- "%s/%s",
- new_dir,
- driver->helpfile);
- if (!old_name) {
- *perr = WERR_NOMEM;
- goto err_exit;
- }
- if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
- new_name = driver_unix_convert(conn,new_name,&st);
- if (!new_name) {
- *perr = WERR_NOMEM;
- goto err_exit;
- }
- if ( !NT_STATUS_IS_OK(copy_file(ctx,conn, new_name, old_name, OPENX_FILE_EXISTS_TRUNCATE|
- OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False))) {
- DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
- new_name, old_name));
- *perr = WERR_ACCESS_DENIED;
+ if (driver->help_file && strlen(driver->help_file)) {
+ if (!strequal(driver->help_file, driver->driver_path) &&
+ !strequal(driver->help_file, driver->data_file) &&
+ !strequal(driver->help_file, driver->config_file)) {
+
+ *perr = move_driver_file_to_download_area(ctx,
+ conn,
+ driver->help_file,
+ short_architecture,
+ driver->version,
+ ver);
+ if (!W_ERROR_IS_OK(*perr)) {
+ if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
ver = -1;
}
+ goto err_exit;
}
}
}
- if (driver->dependentfiles) {
- for (i=0; *driver->dependentfiles[i]; i++) {
- if (!strequal(driver->dependentfiles[i], driver->driverpath) &&
- !strequal(driver->dependentfiles[i], driver->datafile) &&
- !strequal(driver->dependentfiles[i], driver->configfile) &&
- !strequal(driver->dependentfiles[i], driver->helpfile)) {
+ if (driver->dependent_files && driver->dependent_files->string) {
+ for (i=0; driver->dependent_files->string[i]; i++) {
+ if (!strequal(driver->dependent_files->string[i], driver->driver_path) &&
+ !strequal(driver->dependent_files->string[i], driver->data_file) &&
+ !strequal(driver->dependent_files->string[i], driver->config_file) &&
+ !strequal(driver->dependent_files->string[i], driver->help_file)) {
int j;
for (j=0; j < i; j++) {
- if (strequal(driver->dependentfiles[i], driver->dependentfiles[j])) {
+ if (strequal(driver->dependent_files->string[i], driver->dependent_files->string[j])) {
goto NextDriver;
}
}
- new_name = talloc_asprintf(ctx,
- "%s/%s",
- architecture,
- driver->dependentfiles[i]);
- if (!new_name) {
- *perr = WERR_NOMEM;
- goto err_exit;
- }
- old_name = talloc_asprintf(ctx,
- "%s/%s",
- new_dir,
- driver->dependentfiles[i]);
- if (!old_name) {
- *perr = WERR_NOMEM;
- goto err_exit;
- }
- if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
- new_name = driver_unix_convert(conn,new_name,&st);
- if (!new_name) {
- *perr = WERR_NOMEM;
- goto err_exit;
- }
- if ( !NT_STATUS_IS_OK(copy_file(ctx,conn, new_name, old_name,
- OPENX_FILE_EXISTS_TRUNCATE|
- OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False))) {
- DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
- new_name, old_name));
- *perr = WERR_ACCESS_DENIED;
+ *perr = move_driver_file_to_download_area(ctx,
+ conn,
+ driver->dependent_files->string[i],
+ short_architecture,
+ driver->version,
+ ver);
+ if (!W_ERROR_IS_OK(*perr)) {
+ if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
ver = -1;
}
+ goto err_exit;
}
}
NextDriver: ;
}
err_exit:
+ TALLOC_FREE(smb_dname);
if (conn != NULL) {
vfs_ChDir(conn, oldcwd);
- conn_free_internal(conn);
+ conn_free(conn);
}
if (W_ERROR_EQUAL(*perr, WERR_OK)) {
/****************************************************************************
****************************************************************************/
-static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
+static uint32 add_a_printer_driver_3(struct spoolss_AddDriverInfo3 *driver)
{
TALLOC_CTX *ctx = talloc_tos();
int len, buflen;
const char *architecture;
char *directory = NULL;
- fstring temp_name;
char *key = NULL;
uint8 *buf;
int i, ret;
TDB_DATA dbuf;
- architecture = get_short_archi(driver->environment);
+ architecture = get_short_archi(driver->architecture);
if (!architecture) {
return (uint32)-1;
}
*/
directory = talloc_asprintf(ctx, "\\print$\\%s\\%d\\",
- architecture, driver->cversion);
+ architecture, driver->version);
if (!directory) {
return (uint32)-1;
}
+#define gen_full_driver_unc_path(ctx, directory, file) \
+ do { \
+ if (file && strlen(file)) { \
+ file = talloc_asprintf(ctx, "%s%s", directory, file); \
+ } else { \
+ file = talloc_strdup(ctx, ""); \
+ } \
+ if (!file) { \
+ return (uint32_t)-1; \
+ } \
+ } while (0);
+
/* .inf files do not always list a file for each of the four standard files.
* Don't prepend a path to a null filename, or client claims:
* "The server on which the printer resides does not have a suitable
* <printer driver name> printer driver installed. Click OK if you
* wish to install the driver on your local machine."
*/
- if (strlen(driver->driverpath)) {
- fstrcpy(temp_name, driver->driverpath);
- slprintf(driver->driverpath, sizeof(driver->driverpath)-1, "%s%s", directory, temp_name);
- }
-
- if (strlen(driver->datafile)) {
- fstrcpy(temp_name, driver->datafile);
- slprintf(driver->datafile, sizeof(driver->datafile)-1, "%s%s", directory, temp_name);
- }
-
- if (strlen(driver->configfile)) {
- fstrcpy(temp_name, driver->configfile);
- slprintf(driver->configfile, sizeof(driver->configfile)-1, "%s%s", directory, temp_name);
- }
- if (strlen(driver->helpfile)) {
- fstrcpy(temp_name, driver->helpfile);
- slprintf(driver->helpfile, sizeof(driver->helpfile)-1, "%s%s", directory, temp_name);
- }
+ gen_full_driver_unc_path(ctx, directory, driver->driver_path);
+ gen_full_driver_unc_path(ctx, directory, driver->data_file);
+ gen_full_driver_unc_path(ctx, directory, driver->config_file);
+ gen_full_driver_unc_path(ctx, directory, driver->help_file);
- if (driver->dependentfiles) {
- for (i=0; *driver->dependentfiles[i]; i++) {
- fstrcpy(temp_name, driver->dependentfiles[i]);
- slprintf(driver->dependentfiles[i], sizeof(driver->dependentfiles[i])-1, "%s%s", directory, temp_name);
+ if (driver->dependent_files && driver->dependent_files->string) {
+ for (i=0; driver->dependent_files->string[i]; i++) {
+ gen_full_driver_unc_path(ctx, directory,
+ driver->dependent_files->string[i]);
}
}
key = talloc_asprintf(ctx, "%s%s/%d/%s", DRIVERS_PREFIX,
- architecture, driver->cversion, driver->name);
+ architecture, driver->version, driver->driver_name);
if (!key) {
return (uint32)-1;
}
again:
len = 0;
len += tdb_pack(buf+len, buflen-len, "dffffffff",
- driver->cversion,
- driver->name,
- driver->environment,
- driver->driverpath,
- driver->datafile,
- driver->configfile,
- driver->helpfile,
- driver->monitorname,
- driver->defaultdatatype);
-
- if (driver->dependentfiles) {
- for (i=0; *driver->dependentfiles[i]; i++) {
+ driver->version,
+ driver->driver_name,
+ driver->architecture,
+ driver->driver_path,
+ driver->data_file,
+ driver->config_file,
+ driver->help_file,
+ driver->monitor_name ? driver->monitor_name : "",
+ driver->default_datatype ? driver->default_datatype : "");
+
+ if (driver->dependent_files && driver->dependent_files->string) {
+ for (i=0; driver->dependent_files->string[i]; i++) {
len += tdb_pack(buf+len, buflen-len, "f",
- driver->dependentfiles[i]);
+ driver->dependent_files->string[i]);
}
}
/****************************************************************************
****************************************************************************/
-static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
+
+static uint32_t add_a_printer_driver_8(struct spoolss_DriverInfo8 *driver)
{
- NT_PRINTER_DRIVER_INFO_LEVEL_3 info3;
+ TALLOC_CTX *mem_ctx = talloc_new(talloc_tos());
+ struct spoolss_AddDriverInfo3 info3;
+ uint32_t ret;
- ZERO_STRUCT(info3);
- info3.cversion = driver->version;
- fstrcpy(info3.name,driver->name);
- fstrcpy(info3.environment,driver->environment);
- fstrcpy(info3.driverpath,driver->driverpath);
- fstrcpy(info3.datafile,driver->datafile);
- fstrcpy(info3.configfile,driver->configfile);
- fstrcpy(info3.helpfile,driver->helpfile);
- fstrcpy(info3.monitorname,driver->monitorname);
- fstrcpy(info3.defaultdatatype,driver->defaultdatatype);
- info3.dependentfiles = driver->dependentfiles;
-
- return add_a_printer_driver_3(&info3);
-}
+ convert_level_8_to_level3(mem_ctx, &info3, driver);
+
+ ret = add_a_printer_driver_3(&info3);
+ talloc_free(mem_ctx);
+ return ret;
+}
/****************************************************************************
****************************************************************************/
-static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, const char *driver, const char *arch)
-{
- NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
-
- ZERO_STRUCT(info);
- fstrcpy(info.name, driver);
- fstrcpy(info.defaultdatatype, "RAW");
-
- fstrcpy(info.driverpath, "");
- fstrcpy(info.datafile, "");
- fstrcpy(info.configfile, "");
- fstrcpy(info.helpfile, "");
-
- if ((info.dependentfiles= SMB_MALLOC_ARRAY(fstring, 2)) == NULL)
+static WERROR get_a_printer_driver_3_default(TALLOC_CTX *mem_ctx,
+ struct spoolss_DriverInfo3 *info,
+ const char *driver, const char *arch)
+{
+ info->driver_name = talloc_strdup(mem_ctx, driver);
+ if (!info->driver_name) {
return WERR_NOMEM;
+ }
- memset(info.dependentfiles, '\0', 2*sizeof(fstring));
- fstrcpy(info.dependentfiles[0], "");
+ info->default_datatype = talloc_strdup(mem_ctx, "RAW");
+ if (!info->default_datatype) {
+ return WERR_NOMEM;
+ }
- *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&info, sizeof(info));
- if (!*info_ptr) {
- SAFE_FREE(info.dependentfiles);
+ info->driver_path = talloc_strdup(mem_ctx, "");
+ info->data_file = talloc_strdup(mem_ctx, "");
+ info->config_file = talloc_strdup(mem_ctx, "");
+ info->help_file = talloc_strdup(mem_ctx, "");
+ if (!info->driver_path || !info->data_file || !info->config_file || !info->help_file) {
return WERR_NOMEM;
}
/****************************************************************************
****************************************************************************/
-static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr,
+
+static WERROR get_a_printer_driver_3(TALLOC_CTX *mem_ctx,
+ struct spoolss_DriverInfo3 *driver,
const char *drivername, const char *arch,
uint32_t version)
{
- NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
TDB_DATA dbuf;
const char *architecture;
int len = 0;
int i;
char *key = NULL;
-
- ZERO_STRUCT(driver);
+ fstring name, driverpath, environment, datafile, configfile, helpfile, monitorname, defaultdatatype;
architecture = get_short_archi(arch);
if ( !architecture ) {
}
len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff",
- &driver.cversion,
- driver.name,
- driver.environment,
- driver.driverpath,
- driver.datafile,
- driver.configfile,
- driver.helpfile,
- driver.monitorname,
- driver.defaultdatatype);
+ &driver->version,
+ name,
+ environment,
+ driverpath,
+ datafile,
+ configfile,
+ helpfile,
+ monitorname,
+ defaultdatatype);
+
+ driver->driver_name = talloc_strdup(mem_ctx, name);
+ driver->architecture = talloc_strdup(mem_ctx, environment);
+ driver->driver_path = talloc_strdup(mem_ctx, driverpath);
+ driver->data_file = talloc_strdup(mem_ctx, datafile);
+ driver->config_file = talloc_strdup(mem_ctx, configfile);
+ driver->help_file = talloc_strdup(mem_ctx, helpfile);
+ driver->monitor_name = talloc_strdup(mem_ctx, monitorname);
+ driver->default_datatype = talloc_strdup(mem_ctx, defaultdatatype);
i=0;
+
while (len < dbuf.dsize) {
- driver.dependentfiles = SMB_REALLOC_ARRAY(driver.dependentfiles, fstring, i+2);
- if ( !driver.dependentfiles ) {
+
+ fstring file;
+
+ driver->dependent_files = talloc_realloc(mem_ctx, driver->dependent_files, const char *, i+2);
+ if (!driver->dependent_files ) {
DEBUG(0,("get_a_printer_driver_3: failed to enlarge buffer!\n"));
break;
}
len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f",
- &driver.dependentfiles[i]);
+ &file);
+
+ driver->dependent_files[i] = talloc_strdup(mem_ctx, file);
+
i++;
}
- if ( driver.dependentfiles )
- fstrcpy( driver.dependentfiles[i], "" );
+ if (driver->dependent_files)
+ driver->dependent_files[i] = NULL;
SAFE_FREE(dbuf.dptr);
SAFE_FREE(key);
if (len != dbuf.dsize) {
- SAFE_FREE(driver.dependentfiles);
-
- return get_a_printer_driver_3_default(info_ptr, drivername, arch);
- }
-
- *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
- if (!*info_ptr) {
- SAFE_FREE(driver.dependentfiles);
- return WERR_NOMEM;
+ return get_a_printer_driver_3_default(mem_ctx, driver, drivername, arch);
}
return WERR_OK;
}
/****************************************************************************
- Debugging function, dump at level 6 the struct in the logs.
****************************************************************************/
-
-static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
+int pack_devicemode(NT_DEVICEMODE *nt_devmode, uint8 *buf, int buflen)
{
- uint32 result;
- NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
- int i;
+ int len = 0;
- DEBUG(20,("Dumping printer driver at level [%d]\n", level));
-
- switch (level)
- {
- case 3:
- {
- if (driver.info_3 == NULL)
- result=5;
- else {
- info3=driver.info_3;
-
- DEBUGADD(20,("version:[%d]\n", info3->cversion));
- DEBUGADD(20,("name:[%s]\n", info3->name));
- DEBUGADD(20,("environment:[%s]\n", info3->environment));
- DEBUGADD(20,("driverpath:[%s]\n", info3->driverpath));
- DEBUGADD(20,("datafile:[%s]\n", info3->datafile));
- DEBUGADD(20,("configfile:[%s]\n", info3->configfile));
- DEBUGADD(20,("helpfile:[%s]\n", info3->helpfile));
- DEBUGADD(20,("monitorname:[%s]\n", info3->monitorname));
- DEBUGADD(20,("defaultdatatype:[%s]\n", info3->defaultdatatype));
-
- for (i=0; info3->dependentfiles &&
- *info3->dependentfiles[i]; i++) {
- DEBUGADD(20,("dependentfile:[%s]\n",
- info3->dependentfiles[i]));
- }
- result=0;
- }
- break;
- }
- default:
- DEBUGADD(20,("dump_a_printer_driver: Level %u not implemented\n", (unsigned int)level));
- result=1;
- break;
- }
-
- return result;
-}
-
-/****************************************************************************
-****************************************************************************/
-int pack_devicemode(NT_DEVICEMODE *nt_devmode, uint8 *buf, int buflen)
-{
- int len = 0;
-
- len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
+ len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
if (!nt_devmode)
return len;
{
int len = 0;
int i, j;
- REGISTRY_VALUE *val;
- REGVAL_CTR *val_ctr;
+ struct regval_blob *val;
+ struct regval_ctr *val_ctr;
char *path = NULL;
int num_values;
close_all_print_db();
- if (geteuid() == 0) {
+ if (geteuid() == sec_initial_uid()) {
if (asprintf(&printdb_path, "%s%s.tdb",
cache_path("printing/"),
sharename) < 0) {
return ret;
}
+/****************************************************************************
+ Create and allocate a default devicemode.
+****************************************************************************/
+
+WERROR spoolss_create_default_devmode(TALLOC_CTX *mem_ctx,
+ const char *devicename,
+ struct spoolss_DeviceMode **devmode)
+{
+ struct spoolss_DeviceMode *dm;
+ char *dname;
+
+ dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
+ if (dm == NULL) {
+ return WERR_NOMEM;
+ }
+
+ dname = talloc_asprintf(dm, "%s", devicename);
+ if (dname == NULL) {
+ return WERR_NOMEM;
+ }
+ if (strlen(dname) > MAXDEVICENAME) {
+ dname[MAXDEVICENAME] = '\0';
+ }
+ dm->devicename = dname;
+
+ dm->formname = talloc_strdup(dm, "Letter");
+ if (dm->formname == NULL) {
+ return WERR_NOMEM;
+ }
+
+ dm->specversion = DMSPEC_NT4_AND_ABOVE;
+ dm->driverversion = 0x0400;
+ dm->size = 0x00DC;
+ dm->__driverextra_length = 0;
+ dm->fields = DEVMODE_FORMNAME |
+ DEVMODE_TTOPTION |
+ DEVMODE_PRINTQUALITY |
+ DEVMODE_DEFAULTSOURCE |
+ DEVMODE_COPIES |
+ DEVMODE_SCALE |
+ DEVMODE_PAPERSIZE |
+ DEVMODE_ORIENTATION;
+ dm->orientation = DMORIENT_PORTRAIT;
+ dm->papersize = DMPAPER_LETTER;
+ dm->paperlength = 0;
+ dm->paperwidth = 0;
+ dm->scale = 0x64;
+ dm->copies = 1;
+ dm->defaultsource = DMBIN_FORMSOURCE;
+ dm->printquality = DMRES_HIGH; /* 0x0258 */
+ dm->color = DMRES_MONOCHROME;
+ dm->duplex = DMDUP_SIMPLEX;
+ dm->yresolution = 0;
+ dm->ttoption = DMTT_SUBDEV;
+ dm->collate = DMCOLLATE_FALSE;
+ dm->icmmethod = 0;
+ dm->icmintent = 0;
+ dm->mediatype = 0;
+ dm->dithertype = 0;
+
+ dm->logpixels = 0;
+ dm->bitsperpel = 0;
+ dm->pelswidth = 0;
+ dm->pelsheight = 0;
+ dm->displayflags = 0;
+ dm->displayfrequency = 0;
+ dm->reserved1 = 0;
+ dm->reserved2 = 0;
+ dm->panningwidth = 0;
+ dm->panningheight = 0;
+
+ dm->driverextra_data.data = NULL;
+ dm->driverextra_data.length = 0;
+
+ *devmode = dm;
+ return WERR_OK;
+}
+
+WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx,
+ struct spoolss_security_descriptor **secdesc)
+{
+ struct security_ace ace[5]; /* max number of ace entries */
+ int i = 0;
+ uint32_t sa;
+ struct security_acl *psa = NULL;
+ struct security_descriptor *psd = NULL;
+ struct dom_sid adm_sid;
+ size_t sd_size;
+
+ /* Create an ACE where Everyone is allowed to print */
+
+ sa = PRINTER_ACE_PRINT;
+ init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
+ sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
+
+ /* Add the domain admins group if we are a DC */
+
+ if ( IS_DC ) {
+ struct dom_sid domadmins_sid;
+
+ sid_compose(&domadmins_sid, get_global_sam_sid(),
+ DOMAIN_RID_ADMINS);
+
+ sa = PRINTER_ACE_FULL_CONTROL;
+ init_sec_ace(&ace[i++], &domadmins_sid,
+ SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
+ SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
+ init_sec_ace(&ace[i++], &domadmins_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
+ sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
+ }
+ else if (secrets_fetch_domain_sid(lp_workgroup(), &adm_sid)) {
+ sid_append_rid(&adm_sid, DOMAIN_RID_ADMINISTRATOR);
+
+ sa = PRINTER_ACE_FULL_CONTROL;
+ init_sec_ace(&ace[i++], &adm_sid,
+ SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
+ SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
+ init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
+ sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
+ }
+
+ /* add BUILTIN\Administrators as FULL CONTROL */
+
+ sa = PRINTER_ACE_FULL_CONTROL;
+ init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
+ SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
+ SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
+ init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
+ SEC_ACE_TYPE_ACCESS_ALLOWED,
+ sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
+
+ /* Make the security descriptor owned by the BUILTIN\Administrators */
+
+ /* The ACL revision number in rpc_secdesc.h differs from the one
+ created by NT when setting ACE entries in printer
+ descriptors. NT4 complains about the property being edited by a
+ NT5 machine. */
+
+ if ((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) != NULL) {
+ psd = make_sec_desc(mem_ctx,
+ SD_REVISION,
+ SEC_DESC_SELF_RELATIVE,
+ &global_sid_Builtin_Administrators,
+ &global_sid_Builtin_Administrators,
+ NULL,
+ psa,
+ &sd_size);
+ }
+
+ if (psd == NULL) {
+ DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
+ return WERR_NOMEM;
+ }
+
+ DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
+ (unsigned int)sd_size));
+
+ *secdesc = psd;
+
+ return WERR_OK;
+}
/****************************************************************************
Malloc and return an NT devicemode.
fstrcpy(nt_devmode->formname, "Letter");
- nt_devmode->specversion = 0x0401;
+ nt_devmode->specversion = DMSPEC_NT4_AND_ABOVE;
nt_devmode->driverversion = 0x0400;
nt_devmode->size = 0x00DC;
nt_devmode->driverextra = 0x0000;
- nt_devmode->fields = FORMNAME | TTOPTION | PRINTQUALITY |
- DEFAULTSOURCE | COPIES | SCALE |
- PAPERSIZE | ORIENTATION;
- nt_devmode->orientation = 1;
- nt_devmode->papersize = PAPER_LETTER;
+ nt_devmode->fields = DEVMODE_FORMNAME |
+ DEVMODE_TTOPTION |
+ DEVMODE_PRINTQUALITY |
+ DEVMODE_DEFAULTSOURCE |
+ DEVMODE_COPIES |
+ DEVMODE_SCALE |
+ DEVMODE_PAPERSIZE |
+ DEVMODE_ORIENTATION;
+ nt_devmode->orientation = DMORIENT_PORTRAIT;
+ nt_devmode->papersize = DMPAPER_LETTER;
nt_devmode->paperlength = 0;
nt_devmode->paperwidth = 0;
nt_devmode->scale = 0x64;
nt_devmode->copies = 1;
- nt_devmode->defaultsource = BIN_FORMSOURCE;
- nt_devmode->printquality = RES_HIGH; /* 0x0258 */
- nt_devmode->color = COLOR_MONOCHROME;
- nt_devmode->duplex = DUP_SIMPLEX;
+ nt_devmode->defaultsource = DMBIN_FORMSOURCE;
+ nt_devmode->printquality = DMRES_HIGH; /* 0x0258 */
+ nt_devmode->color = DMRES_MONOCHROME;
+ nt_devmode->duplex = DMDUP_SIMPLEX;
nt_devmode->yresolution = 0;
- nt_devmode->ttoption = TT_SUBDEV;
- nt_devmode->collate = COLLATE_FALSE;
+ nt_devmode->ttoption = DMTT_SUBDEV;
+ nt_devmode->collate = DMCOLLATE_FALSE;
nt_devmode->icmmethod = 0;
nt_devmode->icmintent = 0;
nt_devmode->mediatype = 0;
return nt_devmode;
}
-/****************************************************************************
- Deepcopy an NT devicemode.
-****************************************************************************/
-
-NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
-{
- NT_DEVICEMODE *new_nt_devicemode = NULL;
-
- if ( !nt_devicemode )
- return NULL;
-
- if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
- DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
- return NULL;
- }
-
- new_nt_devicemode->nt_dev_private = NULL;
- if (nt_devicemode->nt_dev_private != NULL) {
- if ((new_nt_devicemode->nt_dev_private = (uint8 *)memdup(nt_devicemode->nt_dev_private, nt_devicemode->driverextra)) == NULL) {
- SAFE_FREE(new_nt_devicemode);
- DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
- return NULL;
- }
- }
-
- return new_nt_devicemode;
-}
-
/****************************************************************************
Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
****************************************************************************/
{
NT_PRINTER_KEY *d;
int key_index;
+ WERROR werr;
if ( !name || !data )
return -1;
data->keys[key_index].name = talloc_strdup( data, name );
- if ( !(data->keys[key_index].values = TALLOC_ZERO_P( data, REGVAL_CTR )) )
+ werr = regval_ctr_init(data, &(data->keys[key_index].values));
+ if (!W_ERROR_IS_OK(werr)) {
return -1;
+ }
data->num_keys++;
}
#ifdef HAVE_ADS
-static void map_sz_into_ctr(REGVAL_CTR *ctr, const char *val_name,
+static void map_sz_into_ctr(struct regval_ctr *ctr, const char *val_name,
const char *sz)
{
- smb_ucs2_t conv_str[1024];
- size_t str_size;
-
regval_ctr_delvalue(ctr, val_name);
- str_size = push_ucs2(NULL, conv_str, sz, sizeof(conv_str),
- STR_TERMINATE | STR_NOALIGN);
- regval_ctr_addvalue(ctr, val_name, REG_SZ,
- (char *) conv_str, str_size);
+ regval_ctr_addvalue_sz(ctr, val_name, sz);
}
-static void map_dword_into_ctr(REGVAL_CTR *ctr, const char *val_name,
+static void map_dword_into_ctr(struct regval_ctr *ctr, const char *val_name,
uint32 dword)
{
regval_ctr_delvalue(ctr, val_name);
regval_ctr_addvalue(ctr, val_name, REG_DWORD,
- (char *) &dword, sizeof(dword));
+ (uint8 *) &dword, sizeof(dword));
}
-static void map_bool_into_ctr(REGVAL_CTR *ctr, const char *val_name,
+static void map_bool_into_ctr(struct regval_ctr *ctr, const char *val_name,
bool b)
{
uint8 bin_bool = (b ? 1 : 0);
regval_ctr_delvalue(ctr, val_name);
regval_ctr_addvalue(ctr, val_name, REG_BINARY,
- (char *) &bin_bool, sizeof(bin_bool));
+ (uint8 *) &bin_bool, sizeof(bin_bool));
}
-static void map_single_multi_sz_into_ctr(REGVAL_CTR *ctr, const char *val_name,
+static void map_single_multi_sz_into_ctr(struct regval_ctr *ctr, const char *val_name,
const char *multi_sz)
{
- smb_ucs2_t *conv_strs = NULL;
- size_t str_size;
-
- /* a multi-sz has to have a null string terminator, i.e., the last
- string must be followed by two nulls */
- str_size = strlen(multi_sz) + 2;
- conv_strs = SMB_CALLOC_ARRAY(smb_ucs2_t, str_size);
- if (!conv_strs) {
- return;
- }
+ const char *a[2];
- /* Change to byte units. */
- str_size *= sizeof(smb_ucs2_t);
- push_ucs2(NULL, conv_strs, multi_sz, str_size,
- STR_TERMINATE | STR_NOALIGN);
+ a[0] = multi_sz;
+ a[1] = NULL;
regval_ctr_delvalue(ctr, val_name);
- regval_ctr_addvalue(ctr, val_name, REG_MULTI_SZ,
- (char *) conv_strs, str_size);
- SAFE_FREE(conv_strs);
+ regval_ctr_addvalue_multi_sz(ctr, val_name, a);
}
/****************************************************************************
static bool map_nt_printer_info2_to_dsspooler(NT_PRINTER_INFO_LEVEL_2 *info2)
{
- REGVAL_CTR *ctr = NULL;
+ struct regval_ctr *ctr = NULL;
fstring longname;
const char *dnssuffix;
char *allocated_string = NULL;
struct GUID guid)
{
int i;
- REGVAL_CTR *ctr=NULL;
- UNISTR2 unistr_guid;
+ struct regval_ctr *ctr=NULL;
/* find the DsSpooler key */
if ((i = lookup_printerkey(info2->data, SPOOL_DSSPOOLER_KEY)) < 0)
/* We used to store this as a REG_BINARY but that causes
Vista to whine */
- ZERO_STRUCT( unistr_guid );
-
- init_unistr2( &unistr_guid, GUID_string(talloc_tos(), &guid),
- UNI_STR_TERMINATE );
-
- regval_ctr_addvalue(ctr, "objectGUID", REG_SZ,
- (char *)unistr_guid.buffer,
- unistr_guid.uni_max_len*2);
-
+ regval_ctr_addvalue_sz(ctr, "objectGUID",
+ GUID_string(talloc_tos(), &guid));
}
static WERROR nt_printer_publish_ads(ADS_STRUCT *ads,
struct GUID guid;
WERROR win_rc = WERR_OK;
size_t converted_size;
- int ret;
+
+ /* build the ads mods */
+ ctx = talloc_init("nt_printer_publish_ads");
+ if (ctx == NULL) {
+ return WERR_NOMEM;
+ }
DEBUG(5, ("publishing printer %s\n", printer->info_2->printername));
srv_dn_utf8 = ldap_get_dn((LDAP *)ads->ldap.ld, (LDAPMessage *)res);
if (!srv_dn_utf8) {
+ TALLOC_FREE(ctx);
return WERR_SERVER_UNAVAILABLE;
}
ads_msgfree(ads, res);
srv_cn_utf8 = ldap_explode_dn(srv_dn_utf8, 1);
if (!srv_cn_utf8) {
+ TALLOC_FREE(ctx);
ldap_memfree(srv_dn_utf8);
return WERR_SERVER_UNAVAILABLE;
}
/* Now convert to CH_UNIX. */
- if (!pull_utf8_allocate(&srv_dn, srv_dn_utf8, &converted_size)) {
+ if (!pull_utf8_talloc(ctx, &srv_dn, srv_dn_utf8, &converted_size)) {
+ TALLOC_FREE(ctx);
ldap_memfree(srv_dn_utf8);
ldap_memfree(srv_cn_utf8);
return WERR_SERVER_UNAVAILABLE;
}
- if (!pull_utf8_allocate(&srv_cn_0, srv_cn_utf8[0], &converted_size)) {
+ if (!pull_utf8_talloc(ctx, &srv_cn_0, srv_cn_utf8[0], &converted_size)) {
+ TALLOC_FREE(ctx);
ldap_memfree(srv_dn_utf8);
ldap_memfree(srv_cn_utf8);
- SAFE_FREE(srv_dn);
+ TALLOC_FREE(srv_dn);
return WERR_SERVER_UNAVAILABLE;
}
srv_cn_escaped = escape_rdn_val_string_alloc(srv_cn_0);
if (!srv_cn_escaped) {
- SAFE_FREE(srv_cn_0);
- SAFE_FREE(srv_dn);
+ TALLOC_FREE(ctx);
return WERR_SERVER_UNAVAILABLE;
}
sharename_escaped = escape_rdn_val_string_alloc(printer->info_2->sharename);
if (!sharename_escaped) {
SAFE_FREE(srv_cn_escaped);
- SAFE_FREE(srv_cn_0);
- SAFE_FREE(srv_dn);
+ TALLOC_FREE(ctx);
return WERR_SERVER_UNAVAILABLE;
}
- ret = asprintf(&prt_dn, "cn=%s-%s,%s", srv_cn_escaped, sharename_escaped, srv_dn);
+ prt_dn = talloc_asprintf(ctx, "cn=%s-%s,%s", srv_cn_escaped, sharename_escaped, srv_dn);
- SAFE_FREE(srv_dn);
- SAFE_FREE(srv_cn_0);
SAFE_FREE(srv_cn_escaped);
SAFE_FREE(sharename_escaped);
- if (ret == -1) {
- return WERR_NOMEM;
- }
-
- /* build the ads mods */
- ctx = talloc_init("nt_printer_publish_ads");
- if (ctx == NULL) {
- SAFE_FREE(prt_dn);
- return WERR_NOMEM;
- }
-
mods = ads_init_mods(ctx);
if (mods == NULL) {
SAFE_FREE(prt_dn);
- talloc_destroy(ctx);
+ TALLOC_FREE(ctx);
return WERR_NOMEM;
}
if (!ADS_ERR_OK(ads_rc))
DEBUG(3, ("error publishing %s: %s\n", printer->info_2->sharename, ads_errstr(ads_rc)));
- talloc_destroy(ctx);
-
/* retreive the guid and store it locally */
if (ADS_ERR_OK(ads_search_dn(ads, &res, prt_dn, attrs))) {
ZERO_STRUCT(guid);
store_printer_guid(printer->info_2, guid);
win_rc = mod_a_printer(printer, 2);
}
+ TALLOC_FREE(ctx);
- SAFE_FREE(prt_dn);
return win_rc;
}
printer->info_2->sharename, global_myname());
if (ADS_ERR_OK(ads_rc) && res && ads_count_replies(ads, res)) {
- prt_dn = ads_get_dn(ads, res);
+ prt_dn = ads_get_dn(ads, talloc_tos(), res);
if (!prt_dn) {
ads_msgfree(ads, res);
return WERR_NOMEM;
}
ads_rc = ads_del_dn(ads, prt_dn);
- ads_memfree(ads, prt_dn);
+ TALLOC_FREE(prt_dn);
}
if (res) {
struct GUID *guid)
{
NT_PRINTER_INFO_LEVEL *printer = NULL;
- REGVAL_CTR *ctr;
- REGISTRY_VALUE *guid_val;
+ struct regval_ctr *ctr;
+ struct regval_blob *guid_val;
WERROR win_rc;
int i;
bool ret = False;
+ DATA_BLOB blob;
win_rc = get_a_printer(print_hnd, &printer, 2, lp_servicename(snum));
/* fetching printer guids really ought to be a separate function. */
if ( guid ) {
- fstring guid_str;
+ char *guid_str;
/* We used to store the guid as REG_BINARY, then swapped
to REG_SZ for Vista compatibility so check for both */
switch ( regval_type(guid_val) ){
case REG_SZ:
- rpcstr_pull( guid_str, regval_data_p(guid_val),
- sizeof(guid_str)-1, -1, STR_TERMINATE );
+ blob = data_blob_const(regval_data_p(guid_val),
+ regval_size(guid_val));
+ pull_reg_sz(talloc_tos(), &blob, (const char **)&guid_str);
ret = NT_STATUS_IS_OK(GUID_from_string( guid_str, guid ));
+ talloc_free(guid_str);
break;
case REG_BINARY:
if ( regval_size(guid_val) != sizeof(struct GUID) ) {
return WERR_NOMEM;
regval_ctr_addvalue( p2->data->keys[key_index].values, value,
- type, (const char *)data, real_len );
+ type, data, real_len );
DEBUG(8,("add_printer_data: Added key => [%s], value => [%s], type=> [%d], size => [%d]\n",
key, value, type, real_len ));
/****************************************************************************
***************************************************************************/
-REGISTRY_VALUE* get_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value )
+struct regval_blob* get_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value )
{
int key_index;
char *str;
int size;
uint8 *data_p;
- REGISTRY_VALUE *regval_p;
+ struct regval_blob *regval_p;
int key_index;
/* add the "PrinterDriverData" key first for performance reasons */
strequal( valuename, "objectGUID" ) )
{
struct GUID guid;
- UNISTR2 unistr_guid;
-
- ZERO_STRUCT( unistr_guid );
/* convert the GUID to a UNICODE string */
memcpy( &guid, data_p, sizeof(struct GUID) );
- init_unistr2( &unistr_guid,
- GUID_string(talloc_tos(), &guid),
- UNI_STR_TERMINATE );
-
- regval_ctr_addvalue( printer_data->keys[key_index].values,
- valuename, REG_SZ,
- (const char *)unistr_guid.buffer,
- unistr_guid.uni_str_len*2 );
+ regval_ctr_addvalue_sz(printer_data->keys[key_index].values,
+ valuename,
+ GUID_string(talloc_tos(), &guid));
} else {
/* add the value */
regval_ctr_addvalue( printer_data->keys[key_index].values,
- valuename, type, (const char *)data_p,
+ valuename, type, data_p,
size );
}
/****************************************************************************
***************************************************************************/
-static char *last_from;
-static char *last_to;
+static char *win_driver;
+static char *os2_driver;
-static const char *get_last_from(void)
+static const char *get_win_driver(void)
{
- if (!last_from) {
+ if (win_driver == NULL) {
return "";
}
- return last_from;
+ return win_driver;
}
-static const char *get_last_to(void)
+static const char *get_os2_driver(void)
{
- if (!last_to) {
+ if (os2_driver == NULL) {
return "";
}
- return last_to;
+ return os2_driver;
}
-static bool set_last_from_to(const char *from, const char *to)
+static bool set_driver_mapping(const char *from, const char *to)
{
- char *orig_from = last_from;
- char *orig_to = last_to;
-
- last_from = SMB_STRDUP(from);
- last_to = SMB_STRDUP(to);
+ SAFE_FREE(win_driver);
+ SAFE_FREE(os2_driver);
- SAFE_FREE(orig_from);
- SAFE_FREE(orig_to);
+ win_driver = SMB_STRDUP(from);
+ os2_driver = SMB_STRDUP(to);
- if (!last_from || !last_to) {
- SAFE_FREE(last_from);
- SAFE_FREE(last_to);
+ if (win_driver == NULL || os2_driver == NULL) {
+ SAFE_FREE(win_driver);
+ SAFE_FREE(os2_driver);
return false;
}
return true;
if (!*mapfile)
return;
- if (strequal(drivername,get_last_from())) {
+ if (strequal(drivername, get_win_driver())) {
DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",
- drivername,get_last_to()));
- fstrcpy(drivername,get_last_to());
+ drivername, get_os2_driver()));
+ fstrcpy(drivername, get_os2_driver());
return;
}
if (strequal(nt_name,drivername)) {
DEBUG(3,("Mapped windows driver %s to os2 driver%s\n",drivername,os2_name));
- set_last_from_to(drivername,os2_name);
+ set_driver_mapping(drivername,os2_name);
fstrcpy(drivername,os2_name);
TALLOC_FREE(lines);
return;
TALLOC_FREE(lines);
}
+/**
+ * @internal
+ *
+ * @brief Map a Windows driver to a OS/2 driver.
+ *
+ * @param[in] mem_ctx The memory context to use.
+ *
+ * @param[in,out] pdrivername The drivername of Windows to remap.
+ *
+ * @return WERR_OK on success, a corresponding WERROR on failure.
+ */
+WERROR spoolss_map_to_os2_driver(TALLOC_CTX *mem_ctx, const char **pdrivername)
+{
+ const char *mapfile = lp_os2_driver_map();
+ char **lines = NULL;
+ const char *drivername;
+ int numlines = 0;
+ int i;
+
+ if (pdrivername == NULL || *pdrivername == NULL || *pdrivername[0] == '\0') {
+ return WERR_INVALID_PARAMETER;
+ }
+
+ drivername = *pdrivername;
+
+ if (mapfile[0] == '\0') {
+ return WERR_BADFILE;
+ }
+
+ if (strequal(drivername, get_win_driver())) {
+ DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",
+ drivername, get_os2_driver()));
+ drivername = talloc_strdup(mem_ctx, get_os2_driver());
+ if (drivername == NULL) {
+ return WERR_NOMEM;
+ }
+ *pdrivername = drivername;
+ return WERR_OK;
+ }
+
+ lines = file_lines_load(mapfile, &numlines, 0, NULL);
+ if (numlines == 0 || lines == NULL) {
+ DEBUG(0,("No entries in OS/2 driver map %s\n", mapfile));
+ TALLOC_FREE(lines);
+ return WERR_EMPTY;
+ }
+
+ DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile));
+
+ for( i = 0; i < numlines; i++) {
+ char *nt_name = lines[i];
+ char *os2_name = strchr(nt_name, '=');
+
+ if (os2_name == NULL) {
+ continue;
+ }
+
+ *os2_name++ = '\0';
+
+ while (isspace(*nt_name)) {
+ nt_name++;
+ }
+
+ if (*nt_name == '\0' || strchr("#;", *nt_name)) {
+ continue;
+ }
+
+ {
+ int l = strlen(nt_name);
+ while (l && isspace(nt_name[l - 1])) {
+ nt_name[l - 1] = 0;
+ l--;
+ }
+ }
+
+ while (isspace(*os2_name)) {
+ os2_name++;
+ }
+
+ {
+ int l = strlen(os2_name);
+ while (l && isspace(os2_name[l-1])) {
+ os2_name[l-1] = 0;
+ l--;
+ }
+ }
+
+ if (strequal(nt_name, drivername)) {
+ DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",drivername,os2_name));
+ set_driver_mapping(drivername, os2_name);
+ drivername = talloc_strdup(mem_ctx, os2_name);
+ TALLOC_FREE(lines);
+ if (drivername == NULL) {
+ return WERR_NOMEM;
+ }
+ *pdrivername = drivername;
+ return WERR_OK;
+ }
+ }
+
+ TALLOC_FREE(lines);
+ return WERR_OK;
+}
+
/****************************************************************************
Get a default printer info 2 struct.
****************************************************************************/
if (get_loc_com && (enum printing_types)lp_printing(snum) == PRINT_CUPS ) {
/* Pull the location and comment strings from cups if we don't
already have one */
- if ( !strlen(info->location) || !strlen(info->comment) )
- cups_pull_comment_location( info );
+ if ( !strlen(info->location) || !strlen(info->comment) ) {
+ char *comment = NULL;
+ char *location = NULL;
+ if (cups_pull_comment_location(info, info->sharename,
+ &comment, &location)) {
+ strlcpy(info->comment, comment, sizeof(info->comment));
+ fstrcpy(info->location, location);
+ TALLOC_FREE(comment);
+ TALLOC_FREE(location);
+ }
+ }
}
#endif
goto fail;
}
+ info->data = TALLOC_ZERO_P(info, NT_PRINTER_DATA);
+ if (!info->data) {
+ goto fail;
+ }
+
+ add_new_printer_key(info->data, SPOOL_PRINTERDATA_KEY);
+
return WERR_OK;
fail:
if (get_loc_com && (enum printing_types)lp_printing(snum) == PRINT_CUPS ) {
/* Pull the location and comment strings from cups if we don't
already have one */
- if ( !strlen(info->location) || !strlen(info->comment) )
- cups_pull_comment_location( info );
+ if ( !strlen(info->location) || !strlen(info->comment) ) {
+ char *location = NULL;
+ comment = NULL;
+ if (cups_pull_comment_location(info, info->sharename,
+ &comment, &location)) {
+ strlcpy(info->comment, comment, sizeof(info->comment));
+ fstrcpy(info->location, location);
+ TALLOC_FREE(comment);
+ TALLOC_FREE(location);
+ }
+ }
}
#endif
}
/****************************************************************************
- Initialize printer devmode & data with previously saved driver init values.
+ Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
+
+ Previously the code had a memory allocation problem because it always
+ used the TALLOC_CTX from the Printer_entry*. This context lasts
+ as a long as the original handle is open. So if the client made a lot
+ of getprinter[data]() calls, the memory usage would climb. Now we use
+ a short lived TALLOC_CTX for printer_info_2 objects returned. We
+ still use the Printer_entry->ctx for maintaining the cache copy though
+ since that object must live as long as the handle by definition.
+ --jerry
+
****************************************************************************/
-static bool set_driver_init_2( NT_PRINTER_INFO_LEVEL_2 *info_ptr )
+static WERROR get_a_printer_internal( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level,
+ const char *sharename, bool get_loc_com)
{
- int len = 0;
- char *key = NULL;
- TDB_DATA dbuf;
- NT_PRINTER_INFO_LEVEL_2 info;
+ WERROR result;
+ fstring servername;
+ DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
- ZERO_STRUCT(info);
+ if ( !(*pp_printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) {
+ DEBUG(0,("get_a_printer: talloc() fail.\n"));
+ return WERR_NOMEM;
+ }
- /*
- * Delete any printer data 'values' already set. When called for driver
- * replace, there will generally be some, but during an add printer, there
- * should not be any (if there are delete them).
- */
+ switch (level) {
+ case 2:
+ if ( !((*pp_printer)->info_2 = TALLOC_ZERO_P(*pp_printer, NT_PRINTER_INFO_LEVEL_2)) ) {
+ DEBUG(0,("get_a_printer: talloc() fail.\n"));
+ TALLOC_FREE( *pp_printer );
+ return WERR_NOMEM;
+ }
- if ( info_ptr->data )
- delete_all_printer_data( info_ptr, "" );
+ if ( print_hnd )
+ fstrcpy( servername, print_hnd->servername );
+ else {
+ fstrcpy( servername, "%L" );
+ standard_sub_basic( "", "", servername,
+ sizeof(servername)-1 );
+ }
- if (asprintf(&key, "%s%s", DRIVER_INIT_PREFIX,
- info_ptr->drivername) < 0) {
- return false;
- }
-
- dbuf = tdb_fetch_bystring(tdb_drivers, key);
- if (!dbuf.dptr) {
- /*
- * When changing to a driver that has no init info in the tdb, remove
- * the previous drivers init info and leave the new on blank.
- */
- free_nt_devicemode(&info_ptr->devmode);
- SAFE_FREE(key);
- return false;
- }
-
- SAFE_FREE(key);
- /*
- * Get the saved DEVMODE..
- */
-
- len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
-
- /*
- * The saved DEVMODE contains the devicename from the printer used during
- * the initialization save. Change it to reflect the new printer.
- */
-
- if ( info.devmode ) {
- ZERO_STRUCT(info.devmode->devicename);
- fstrcpy(info.devmode->devicename, info_ptr->printername);
- }
-
- /*
- * NT/2k does not change out the entire DeviceMode of a printer
- * when changing the driver. Only the driverextra, private, &
- * driverversion fields. --jerry (Thu Mar 14 08:58:43 CST 2002)
- *
- * Later examination revealed that Windows NT/2k does reset the
- * the printer's device mode, bit **only** when you change a
- * property of the device mode such as the page orientation.
- * --jerry
- */
-
-
- /* Bind the saved DEVMODE to the new the printer */
-
- free_nt_devicemode(&info_ptr->devmode);
- info_ptr->devmode = info.devmode;
-
- DEBUG(10,("set_driver_init_2: Set printer [%s] init %s DEVMODE for driver [%s]\n",
- info_ptr->printername, info_ptr->devmode?"VALID":"NULL", info_ptr->drivername));
-
- /* Add the printer data 'values' to the new printer */
-
- if ( !(info_ptr->data = TALLOC_ZERO_P( info_ptr, NT_PRINTER_DATA )) ) {
- DEBUG(0,("set_driver_init_2: talloc() failed!\n"));
- return False;
- }
-
- len += unpack_values( info_ptr->data, dbuf.dptr+len, dbuf.dsize-len );
-
- SAFE_FREE(dbuf.dptr);
-
- return true;
-}
-
-/****************************************************************************
- Initialize printer devmode & data with previously saved driver init values.
- When a printer is created using AddPrinter, the drivername bound to the
- printer is used to lookup previously saved driver initialization info, which
- is bound to the new printer.
-****************************************************************************/
-
-bool set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
-{
- bool result = False;
-
- switch (level) {
- case 2:
- result = set_driver_init_2(printer->info_2);
- break;
-
- default:
- DEBUG(0,("set_driver_init: Programmer's error! Unknown driver_init level [%d]\n",
- level));
- break;
- }
-
- return result;
-}
-
-/****************************************************************************
- Delete driver init data stored for a specified driver
-****************************************************************************/
-
-bool del_driver_init(const char *drivername)
-{
- char *key;
- bool ret;
-
- if (!drivername || !*drivername) {
- DEBUG(3,("del_driver_init: No drivername specified!\n"));
- return false;
- }
-
- if (asprintf(&key, "%s%s", DRIVER_INIT_PREFIX, drivername) < 0) {
- return false;
- }
-
- DEBUG(6,("del_driver_init: Removing driver init data for [%s]\n",
- drivername));
-
- ret = (tdb_delete_bystring(tdb_drivers, key) == 0);
- SAFE_FREE(key);
- return ret;
-}
-
-/****************************************************************************
- Pack up the DEVMODE and values for a printer into a 'driver init' entry
- in the tdb. Note: this is different from the driver entry and the printer
- entry. There should be a single driver init entry for each driver regardless
- of whether it was installed from NT or 2K. Technically, they should be
- different, but they work out to the same struct.
-****************************************************************************/
-
-static uint32 update_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info)
-{
- char *key = NULL;
- uint8 *buf;
- int buflen, len, ret;
- int retlen;
- TDB_DATA dbuf;
-
- buf = NULL;
- buflen = 0;
-
- again:
- len = 0;
- len += pack_devicemode(info->devmode, buf+len, buflen-len);
-
- retlen = pack_values( info->data, buf+len, buflen-len );
- if (retlen == -1) {
- ret = -1;
- goto done;
- }
- len += retlen;
-
- if (buflen < len) {
- buf = (uint8 *)SMB_REALLOC(buf, len);
- if (!buf) {
- DEBUG(0, ("update_driver_init_2: failed to enlarge buffer!\n"));
- ret = -1;
- goto done;
- }
- buflen = len;
- goto again;
- }
-
- SAFE_FREE(key);
- if (asprintf(&key, "%s%s", DRIVER_INIT_PREFIX, info->drivername) < 0) {
- ret = (uint32)-1;
- goto done;
- }
-
- dbuf.dptr = buf;
- dbuf.dsize = len;
-
- ret = tdb_store_bystring(tdb_drivers, key, dbuf, TDB_REPLACE);
-
-done:
- if (ret == -1)
- DEBUG(8, ("update_driver_init_2: error updating printer init to tdb on disk\n"));
-
- SAFE_FREE(buf);
-
- DEBUG(10,("update_driver_init_2: Saved printer [%s] init DEVMODE & values for driver [%s]\n",
- info->sharename, info->drivername));
-
- return ret;
-}
-
-/****************************************************************************
- Update (i.e. save) the driver init info (DEVMODE and values) for a printer
-****************************************************************************/
-
-static uint32 update_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
-{
- uint32 result;
-
- dump_a_printer(printer, level);
-
- switch (level) {
- case 2:
- result = update_driver_init_2(printer->info_2);
- break;
- default:
- result = 1;
- break;
- }
-
- return result;
-}
-
-/****************************************************************************
- Convert the printer data value, a REG_BINARY array, into an initialization
- DEVMODE. Note: the array must be parsed as if it was a DEVMODE in an rpc...
- got to keep the endians happy :).
-****************************************************************************/
-
-static bool convert_driver_init(TALLOC_CTX *mem_ctx, NT_DEVICEMODE *nt_devmode,
- const uint8_t *data, uint32_t data_len)
-{
- struct spoolss_DeviceMode devmode;
- enum ndr_err_code ndr_err;
- DATA_BLOB blob;
-
- ZERO_STRUCT(devmode);
-
- blob = data_blob_const(data, data_len);
-
- ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL, &devmode,
- (ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- DEBUG(10,("convert_driver_init: error parsing spoolss_DeviceMode\n"));
- return false;
- }
-
- return convert_devicemode("", &devmode, &nt_devmode);
-}
-
-/****************************************************************************
- Set the DRIVER_INIT info in the tdb. Requires Win32 client code that:
-
- 1. Use the driver's config DLL to this UNC printername and:
- a. Call DrvPrintEvent with PRINTER_EVENT_INITIALIZE
- b. Call DrvConvertDevMode with CDM_DRIVER_DEFAULT to get default DEVMODE
- 2. Call SetPrinterData with the 'magic' key and the DEVMODE as data.
-
- The last step triggers saving the "driver initialization" information for
- this printer into the tdb. Later, new printers that use this driver will
- have this initialization information bound to them. This simulates the
- driver initialization, as if it had run on the Samba server (as it would
- have done on NT).
-
- The Win32 client side code requirement sucks! But until we can run arbitrary
- Win32 printer driver code on any Unix that Samba runs on, we are stuck with it.
-
- It would have been easier to use SetPrinter because all the UNMARSHALLING of
- the DEVMODE is done there, but 2K/XP clients do not set the DEVMODE... think
- about it and you will realize why. JRR 010720
-****************************************************************************/
-
-static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, uint8 *data, uint32 data_len )
-{
- WERROR status = WERR_OK;
- TALLOC_CTX *ctx = NULL;
- NT_DEVICEMODE *nt_devmode = NULL;
- NT_DEVICEMODE *tmp_devmode = printer->info_2->devmode;
-
- /*
- * When the DEVMODE is already set on the printer, don't try to unpack it.
- */
- DEBUG(8,("save_driver_init_2: Enter...\n"));
-
- if ( !printer->info_2->devmode && data_len ) {
- /*
- * Set devmode on printer info, so entire printer initialization can be
- * saved to tdb.
- */
-
- if ((ctx = talloc_init("save_driver_init_2")) == NULL)
- return WERR_NOMEM;
-
- if ((nt_devmode = SMB_MALLOC_P(NT_DEVICEMODE)) == NULL) {
- status = WERR_NOMEM;
- goto done;
- }
-
- ZERO_STRUCTP(nt_devmode);
-
- /*
- * The DEVMODE is held in the 'data' component of the param in raw binary.
- * Convert it to to a devmode structure
- */
- if ( !convert_driver_init( ctx, nt_devmode, data, data_len )) {
- DEBUG(10,("save_driver_init_2: error converting DEVMODE\n"));
- status = WERR_INVALID_PARAM;
- goto done;
- }
-
- printer->info_2->devmode = nt_devmode;
- }
-
- /*
- * Pack up and add (or update) the DEVMODE and any current printer data to
- * a 'driver init' element in the tdb
- *
- */
-
- if ( update_driver_init(printer, 2) != 0 ) {
- DEBUG(10,("save_driver_init_2: error updating DEVMODE\n"));
- status = WERR_NOMEM;
- goto done;
- }
-
- /*
- * If driver initialization info was successfully saved, set the current
- * printer to match it. This allows initialization of the current printer
- * as well as the driver.
- */
- status = mod_a_printer(printer, 2);
- if (!W_ERROR_IS_OK(status)) {
- DEBUG(10,("save_driver_init_2: error setting DEVMODE on printer [%s]\n",
- printer->info_2->printername));
- }
-
- done:
- talloc_destroy(ctx);
- free_nt_devicemode( &nt_devmode );
-
- printer->info_2->devmode = tmp_devmode;
-
- return status;
-}
-
-/****************************************************************************
- Update the driver init info (DEVMODE and specifics) for a printer
-****************************************************************************/
-
-WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, uint8 *data, uint32 data_len)
-{
- WERROR status = WERR_OK;
-
- switch (level) {
- case 2:
- status = save_driver_init_2( printer, data, data_len );
- break;
- default:
- status = WERR_UNKNOWN_LEVEL;
- break;
- }
-
- return status;
-}
-
-/****************************************************************************
- Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
-
- Previously the code had a memory allocation problem because it always
- used the TALLOC_CTX from the Printer_entry*. This context lasts
- as a long as the original handle is open. So if the client made a lot
- of getprinter[data]() calls, the memory usage would climb. Now we use
- a short lived TALLOC_CTX for printer_info_2 objects returned. We
- still use the Printer_entry->ctx for maintaining the cache copy though
- since that object must live as long as the handle by definition.
- --jerry
-
-****************************************************************************/
-
-static WERROR get_a_printer_internal( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level,
- const char *sharename, bool get_loc_com)
-{
- WERROR result;
- fstring servername;
-
- DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
-
- if ( !(*pp_printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) {
- DEBUG(0,("get_a_printer: talloc() fail.\n"));
- return WERR_NOMEM;
- }
-
- switch (level) {
- case 2:
- if ( !((*pp_printer)->info_2 = TALLOC_ZERO_P(*pp_printer, NT_PRINTER_INFO_LEVEL_2)) ) {
- DEBUG(0,("get_a_printer: talloc() fail.\n"));
- TALLOC_FREE( *pp_printer );
- return WERR_NOMEM;
- }
-
- if ( print_hnd )
- fstrcpy( servername, print_hnd->servername );
- else {
- fstrcpy( servername, "%L" );
- standard_sub_basic( "", "", servername,
- sizeof(servername)-1 );
- }
-
- result = get_a_printer_2( (*pp_printer)->info_2,
- servername, sharename, get_loc_com);
+ result = get_a_printer_2( (*pp_printer)->info_2,
+ servername, sharename, get_loc_com);
/* we have a new printer now. Save it with this handle */
/****************************************************************************
****************************************************************************/
-uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
+
+bool driver_info_ctr_to_info8(struct spoolss_AddDriverInfoCtr *r,
+ struct spoolss_DriverInfo8 *_info8)
{
- uint32 result;
- DEBUG(104,("adding a printer at level [%d]\n", level));
- dump_a_printer_driver(driver, level);
+ struct spoolss_DriverInfo8 info8;
+
+ ZERO_STRUCT(info8);
+
+ switch (r->level) {
+ case 3:
+ info8.version = r->info.info3->version;
+ info8.driver_name = r->info.info3->driver_name;
+ info8.architecture = r->info.info3->architecture;
+ info8.driver_path = r->info.info3->driver_path;
+ info8.data_file = r->info.info3->data_file;
+ info8.config_file = r->info.info3->config_file;
+ info8.help_file = r->info.info3->help_file;
+ info8.monitor_name = r->info.info3->monitor_name;
+ info8.default_datatype = r->info.info3->default_datatype;
+ if (r->info.info3->dependent_files && r->info.info3->dependent_files->string) {
+ info8.dependent_files = r->info.info3->dependent_files->string;
+ }
+ break;
+ case 6:
+ info8.version = r->info.info6->version;
+ info8.driver_name = r->info.info6->driver_name;
+ info8.architecture = r->info.info6->architecture;
+ info8.driver_path = r->info.info6->driver_path;
+ info8.data_file = r->info.info6->data_file;
+ info8.config_file = r->info.info6->config_file;
+ info8.help_file = r->info.info6->help_file;
+ info8.monitor_name = r->info.info6->monitor_name;
+ info8.default_datatype = r->info.info6->default_datatype;
+ if (r->info.info6->dependent_files && r->info.info6->dependent_files->string) {
+ info8.dependent_files = r->info.info6->dependent_files->string;
+ }
+ info8.driver_date = r->info.info6->driver_date;
+ info8.driver_version = r->info.info6->driver_version;
+ info8.manufacturer_name = r->info.info6->manufacturer_name;
+ info8.manufacturer_url = r->info.info6->manufacturer_url;
+ info8.hardware_id = r->info.info6->hardware_id;
+ info8.provider = r->info.info6->provider;
+ break;
+ case 8:
+ info8.version = r->info.info8->version;
+ info8.driver_name = r->info.info8->driver_name;
+ info8.architecture = r->info.info8->architecture;
+ info8.driver_path = r->info.info8->driver_path;
+ info8.data_file = r->info.info8->data_file;
+ info8.config_file = r->info.info8->config_file;
+ info8.help_file = r->info.info8->help_file;
+ info8.monitor_name = r->info.info8->monitor_name;
+ info8.default_datatype = r->info.info8->default_datatype;
+ if (r->info.info8->dependent_files && r->info.info8->dependent_files->string) {
+ info8.dependent_files = r->info.info8->dependent_files->string;
+ }
+ if (r->info.info8->previous_names && r->info.info8->previous_names->string) {
+ info8.previous_names = r->info.info8->previous_names->string;
+ }
+ info8.driver_date = r->info.info8->driver_date;
+ info8.driver_version = r->info.info8->driver_version;
+ info8.manufacturer_name = r->info.info8->manufacturer_name;
+ info8.manufacturer_url = r->info.info8->manufacturer_url;
+ info8.hardware_id = r->info.info8->hardware_id;
+ info8.provider = r->info.info8->provider;
+ info8.print_processor = r->info.info8->print_processor;
+ info8.vendor_setup = r->info.info8->vendor_setup;
+ if (r->info.info8->color_profiles && r->info.info8->color_profiles->string) {
+ info8.color_profiles = r->info.info8->color_profiles->string;
+ }
+ info8.inf_path = r->info.info8->inf_path;
+ info8.printer_driver_attributes = r->info.info8->printer_driver_attributes;
+ if (r->info.info8->core_driver_dependencies && r->info.info8->core_driver_dependencies->string) {
+ info8.core_driver_dependencies = r->info.info8->core_driver_dependencies->string;
+ }
+ info8.min_inbox_driver_ver_date = r->info.info8->min_inbox_driver_ver_date;
+ info8.min_inbox_driver_ver_version = r->info.info8->min_inbox_driver_ver_version;
+ break;
+ default:
+ return false;
+ }
- switch (level) {
- case 3:
- result=add_a_printer_driver_3(driver.info_3);
- break;
+ *_info8 = info8;
- case 6:
- result=add_a_printer_driver_6(driver.info_6);
- break;
+ return true;
+}
- default:
- result=1;
- break;
+
+uint32_t add_a_printer_driver(TALLOC_CTX *mem_ctx,
+ struct spoolss_AddDriverInfoCtr *r,
+ char **driver_name,
+ uint32_t *version)
+{
+ struct spoolss_DriverInfo8 info8;
+
+ ZERO_STRUCT(info8);
+
+ DEBUG(10,("adding a printer at level [%d]\n", r->level));
+
+ if (!driver_info_ctr_to_info8(r, &info8)) {
+ return -1;
}
- return result;
+ *driver_name = talloc_strdup(mem_ctx, info8.driver_name);
+ if (!*driver_name) {
+ return -1;
+ }
+ *version = info8.version;
+
+ return add_a_printer_driver_8(&info8);
}
+
/****************************************************************************
****************************************************************************/
-WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32_t level,
+WERROR get_a_printer_driver(TALLOC_CTX *mem_ctx,
+ struct spoolss_DriverInfo8 **driver,
const char *drivername, const char *architecture,
uint32_t version)
{
WERROR result;
+ struct spoolss_DriverInfo3 info3;
+ struct spoolss_DriverInfo8 *info8;
- switch (level) {
- case 3:
- /* Sometime we just want any version of the driver */
+ ZERO_STRUCT(info3);
+
+ /* Sometime we just want any version of the driver */
- if ( version == DRIVER_ANY_VERSION ) {
- /* look for Win2k first and then for NT4 */
- result = get_a_printer_driver_3(&driver->info_3, drivername,
+ if (version == DRIVER_ANY_VERSION) {
+ /* look for Win2k first and then for NT4 */
+ result = get_a_printer_driver_3(mem_ctx,
+ &info3,
+ drivername,
architecture, 3);
+ if (!W_ERROR_IS_OK(result)) {
+ result = get_a_printer_driver_3(mem_ctx,
+ &info3,
+ drivername,
+ architecture, 2);
+ }
+ } else {
+ result = get_a_printer_driver_3(mem_ctx,
+ &info3,
+ drivername,
+ architecture,
+ version);
+ }
- if ( !W_ERROR_IS_OK(result) ) {
- result = get_a_printer_driver_3( &driver->info_3,
- drivername, architecture, 2 );
- }
- } else {
- result = get_a_printer_driver_3(&driver->info_3, drivername,
- architecture, version);
- }
- break;
+ if (!W_ERROR_IS_OK(result)) {
+ return result;
+ }
- default:
- result=W_ERROR(1);
- break;
+ info8 = talloc_zero(mem_ctx, struct spoolss_DriverInfo8);
+ if (!info8) {
+ return WERR_NOMEM;
}
- if (W_ERROR_IS_OK(result))
- dump_a_printer_driver(*driver, level);
+ info8->version = info3.version;
+ info8->driver_name = info3.driver_name;
+ info8->architecture = info3.architecture;
+ info8->driver_path = info3.driver_path;
+ info8->data_file = info3.data_file;
+ info8->config_file = info3.config_file;
+ info8->help_file = info3.help_file;
+ info8->dependent_files = info3.dependent_files;
+ info8->monitor_name = info3.monitor_name;
+ info8->default_datatype = info3.default_datatype;
- return result;
+ *driver = info8;
+
+ return WERR_OK;
}
/****************************************************************************
****************************************************************************/
-uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
-{
- uint32 result;
- switch (level) {
- case 3:
- {
- NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
- if (driver.info_3 != NULL)
- {
- info3=driver.info_3;
- SAFE_FREE(info3->dependentfiles);
- ZERO_STRUCTP(info3);
- SAFE_FREE(info3);
- result=0;
- } else {
- result=4;
- }
- break;
- }
- case 6:
- {
- NT_PRINTER_DRIVER_INFO_LEVEL_6 *info6;
- if (driver.info_6 != NULL) {
- info6=driver.info_6;
- SAFE_FREE(info6->dependentfiles);
- SAFE_FREE(info6->previousnames);
- ZERO_STRUCTP(info6);
- SAFE_FREE(info6);
- result=0;
- } else {
- result=4;
- }
- break;
- }
- default:
- result=1;
- break;
- }
- return result;
+uint32_t free_a_printer_driver(struct spoolss_DriverInfo8 *driver)
+{
+ talloc_free(driver);
+ return 0;
}
to a printer
****************************************************************************/
-bool printer_driver_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3 )
+bool printer_driver_in_use(const struct spoolss_DriverInfo8 *r)
{
int snum;
int n_services = lp_numservices();
NT_PRINTER_INFO_LEVEL *printer = NULL;
bool in_use = False;
- if ( !info_3 )
- return False;
+ if (!r) {
+ return false;
+ }
DEBUG(10,("printer_driver_in_use: Beginning search through ntprinters.tdb...\n"));
if ( !W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_servicename(snum))) )
continue;
- if ( strequal(info_3->name, printer->info_2->drivername) )
+ if (strequal(r->driver_name, printer->info_2->drivername))
in_use = True;
free_a_printer( &printer, 2 );
DEBUG(10,("printer_driver_in_use: Completed search through ntprinters.tdb...\n"));
if ( in_use ) {
- NT_PRINTER_DRIVER_INFO_LEVEL d;
+ struct spoolss_DriverInfo8 *d;
WERROR werr;
- DEBUG(5,("printer_driver_in_use: driver \"%s\" is currently in use\n", info_3->name));
+ DEBUG(5,("printer_driver_in_use: driver \"%s\" is currently in use\n", r->driver_name));
/* we can still remove the driver if there is one of
"Windows NT x86" version 2 or 3 left */
- if ( !strequal( "Windows NT x86", info_3->environment ) ) {
- werr = get_a_printer_driver( &d, 3, info_3->name, "Windows NT x86", DRIVER_ANY_VERSION );
+ if (!strequal("Windows NT x86", r->architecture)) {
+ werr = get_a_printer_driver(talloc_tos(), &d, r->driver_name, "Windows NT x86", DRIVER_ANY_VERSION);
}
else {
- switch ( info_3->cversion ) {
+ switch (r->version) {
case 2:
- werr = get_a_printer_driver( &d, 3, info_3->name, "Windows NT x86", 3 );
+ werr = get_a_printer_driver(talloc_tos(), &d, r->driver_name, "Windows NT x86", 3);
break;
case 3:
- werr = get_a_printer_driver( &d, 3, info_3->name, "Windows NT x86", 2 );
+ werr = get_a_printer_driver(talloc_tos(), &d, r->driver_name, "Windows NT x86", 2);
break;
default:
DEBUG(0,("printer_driver_in_use: ERROR! unknown driver version (%d)\n",
- info_3->cversion));
+ r->version));
werr = WERR_UNKNOWN_PRINTER_DRIVER;
break;
}
if ( W_ERROR_IS_OK(werr) ) {
/* it's ok to remove the driver, we have other architctures left */
in_use = False;
- free_a_printer_driver( d, 3 );
+ free_a_printer_driver(d);
}
}
Check to see if a ogiven file is in use by *info
*********************************************************************/
-static bool drv_file_in_use( char* file, NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
+static bool drv_file_in_use(const char *file, const struct spoolss_DriverInfo8 *info)
{
int i = 0;
return false;
}
- if ( strequal(file, info->driverpath) )
+ if (strequal(file, info->driver_path))
return True;
- if ( strequal(file, info->datafile) )
+ if (strequal(file, info->data_file))
return True;
- if ( strequal(file, info->configfile) )
+ if (strequal(file, info->config_file))
return True;
- if ( strequal(file, info->helpfile) )
+ if (strequal(file, info->help_file))
return True;
/* see of there are any dependent files to examine */
- if ( !info->dependentfiles )
+ if (!info->dependent_files)
return False;
- while ( *info->dependentfiles[i] ) {
- if ( strequal(file, info->dependentfiles[i]) )
+ while (info->dependent_files[i] && *info->dependent_files[i]) {
+ if (strequal(file, info->dependent_files[i]))
return True;
i++;
}
input parameter from the list
*********************************************************************/
-static void trim_dependent_file( fstring files[], int idx )
+static void trim_dependent_file(TALLOC_CTX *mem_ctx, const char **files, int idx)
{
/* bump everything down a slot */
- while( *files[idx+1] ) {
- fstrcpy( files[idx], files[idx+1] );
+ while (files && files[idx+1]) {
+ files[idx] = talloc_strdup(mem_ctx, files[idx+1]);
idx++;
}
- *files[idx] = '\0';
+ files[idx] = NULL;
return;
}
Check if any of the files used by src are also used by drv
*********************************************************************/
-static bool trim_overlap_drv_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *src,
- NT_PRINTER_DRIVER_INFO_LEVEL_3 *drv )
+static bool trim_overlap_drv_files(TALLOC_CTX *mem_ctx,
+ struct spoolss_DriverInfo8 *src,
+ const struct spoolss_DriverInfo8 *drv)
{
bool in_use = False;
int i = 0;
/* check each file. Remove it from the src structure if it overlaps */
- if ( drv_file_in_use(src->driverpath, drv) ) {
+ if (drv_file_in_use(src->driver_path, drv)) {
in_use = True;
- DEBUG(10,("Removing driverfile [%s] from list\n", src->driverpath));
- fstrcpy( src->driverpath, "" );
+ DEBUG(10,("Removing driverfile [%s] from list\n", src->driver_path));
+ src->driver_path = talloc_strdup(mem_ctx, "");
+ if (!src->driver_path) { return false; }
}
- if ( drv_file_in_use(src->datafile, drv) ) {
+ if (drv_file_in_use(src->data_file, drv)) {
in_use = True;
- DEBUG(10,("Removing datafile [%s] from list\n", src->datafile));
- fstrcpy( src->datafile, "" );
+ DEBUG(10,("Removing datafile [%s] from list\n", src->data_file));
+ src->data_file = talloc_strdup(mem_ctx, "");
+ if (!src->data_file) { return false; }
}
- if ( drv_file_in_use(src->configfile, drv) ) {
+ if (drv_file_in_use(src->config_file, drv)) {
in_use = True;
- DEBUG(10,("Removing configfile [%s] from list\n", src->configfile));
- fstrcpy( src->configfile, "" );
+ DEBUG(10,("Removing configfile [%s] from list\n", src->config_file));
+ src->config_file = talloc_strdup(mem_ctx, "");
+ if (!src->config_file) { return false; }
}
- if ( drv_file_in_use(src->helpfile, drv) ) {
+ if (drv_file_in_use(src->help_file, drv)) {
in_use = True;
- DEBUG(10,("Removing helpfile [%s] from list\n", src->helpfile));
- fstrcpy( src->helpfile, "" );
+ DEBUG(10,("Removing helpfile [%s] from list\n", src->help_file));
+ src->help_file = talloc_strdup(mem_ctx, "");
+ if (!src->help_file) { return false; }
}
/* are there any dependentfiles to examine? */
- if ( !src->dependentfiles )
+ if (!src->dependent_files)
return in_use;
- while ( *src->dependentfiles[i] ) {
- if ( drv_file_in_use(src->dependentfiles[i], drv) ) {
+ while (src->dependent_files[i] && *src->dependent_files[i]) {
+ if (drv_file_in_use(src->dependent_files[i], drv)) {
in_use = True;
- DEBUG(10,("Removing [%s] from dependent file list\n", src->dependentfiles[i]));
- trim_dependent_file( src->dependentfiles, i );
+ DEBUG(10,("Removing [%s] from dependent file list\n", src->dependent_files[i]));
+ trim_dependent_file(mem_ctx, src->dependent_files, i);
} else
i++;
}
match.
****************************************************************************/
-bool printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
+bool printer_driver_files_in_use(TALLOC_CTX *mem_ctx,
+ struct spoolss_DriverInfo8 *info)
{
int i;
int ndrivers;
uint32 version;
fstring *list = NULL;
- NT_PRINTER_DRIVER_INFO_LEVEL driver;
+ struct spoolss_DriverInfo8 *driver;
bool in_use = false;
if ( !info )
return False;
- version = info->cversion;
+ version = info->version;
/* loop over all driver versions */
/* get the list of drivers */
list = NULL;
- ndrivers = get_ntdrivers(&list, info->environment, version);
+ ndrivers = get_ntdrivers(&list, info->architecture, version);
DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n",
- ndrivers, info->environment, version));
+ ndrivers, info->architecture, version));
/* check each driver for overlap in files */
for (i=0; i<ndrivers; i++) {
DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
- ZERO_STRUCT(driver);
+ driver = NULL;
- if ( !W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, list[i], info->environment, version)) ) {
+ if (!W_ERROR_IS_OK(get_a_printer_driver(talloc_tos(), &driver, list[i], info->architecture, version))) {
SAFE_FREE(list);
return True;
}
/* check if d2 uses any files from d1 */
/* only if this is a different driver than the one being deleted */
- if ( !strequal(info->name, driver.info_3->name) ) {
- if ( trim_overlap_drv_files(info, driver.info_3) ) {
+ if (!strequal(info->driver_name, driver->driver_name)) {
+ if (trim_overlap_drv_files(mem_ctx, info, driver)) {
/* mz: Do not instantly return -
* we need to ensure this file isn't
* also in use by other drivers. */
}
}
- free_a_printer_driver(driver, 3);
+ free_a_printer_driver(driver);
}
SAFE_FREE(list);
DEBUG(5,("printer_driver_files_in_use: Completed search through ntdrivers.tdb...\n"));
- driver.info_3 = info;
+ return in_use;
+}
- if ( DEBUGLEVEL >= 20 )
- dump_a_printer_driver( driver, 3 );
+static NTSTATUS driver_unlink_internals(connection_struct *conn,
+ const char *name)
+{
+ struct smb_filename *smb_fname = NULL;
+ NTSTATUS status;
- return in_use;
+ status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL,
+ &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ status = unlink_internals(conn, NULL, 0, smb_fname, false);
+
+ TALLOC_FREE(smb_fname);
+ return status;
}
/****************************************************************************
****************************************************************************/
static bool delete_driver_files(struct pipes_struct *rpc_pipe,
- NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3)
+ const struct spoolss_DriverInfo8 *r)
{
int i = 0;
char *s;
const char *file;
connection_struct *conn;
NTSTATUS nt_status;
- SMB_STRUCT_STAT st;
char *oldcwd;
fstring printdollar;
int printdollar_snum;
bool ret = false;
- if ( !info_3 )
- return False;
+ if (!r) {
+ return false;
+ }
- DEBUG(6,("delete_driver_files: deleting driver [%s] - version [%d]\n", info_3->name, info_3->cversion));
+ DEBUG(6,("delete_driver_files: deleting driver [%s] - version [%d]\n",
+ r->driver_name, r->version));
fstrcpy(printdollar, "print$");
/* now delete the files; must strip the '\print$' string from
fron of path */
- if ( *info_3->driverpath ) {
- if ( (s = strchr( &info_3->driverpath[1], '\\' )) != NULL ) {
+ if (r->driver_path && r->driver_path[0]) {
+ if ((s = strchr(&r->driver_path[1], '\\')) != NULL) {
file = s;
- driver_unix_convert(conn,file,&st);
DEBUG(10,("deleting driverfile [%s]\n", s));
- unlink_internals(conn, NULL, 0, file, False);
+ driver_unlink_internals(conn, file);
}
}
- if ( *info_3->configfile ) {
- if ( (s = strchr( &info_3->configfile[1], '\\' )) != NULL ) {
+ if (r->config_file && r->config_file[0]) {
+ if ((s = strchr(&r->config_file[1], '\\')) != NULL) {
file = s;
- driver_unix_convert(conn,file,&st);
DEBUG(10,("deleting configfile [%s]\n", s));
- unlink_internals(conn, NULL, 0, file, False);
+ driver_unlink_internals(conn, file);
}
}
- if ( *info_3->datafile ) {
- if ( (s = strchr( &info_3->datafile[1], '\\' )) != NULL ) {
+ if (r->data_file && r->data_file[0]) {
+ if ((s = strchr(&r->data_file[1], '\\')) != NULL) {
file = s;
- driver_unix_convert(conn,file,&st);
DEBUG(10,("deleting datafile [%s]\n", s));
- unlink_internals(conn, NULL, 0, file, False);
+ driver_unlink_internals(conn, file);
}
}
- if ( *info_3->helpfile ) {
- if ( (s = strchr( &info_3->helpfile[1], '\\' )) != NULL ) {
+ if (r->help_file && r->help_file[0]) {
+ if ((s = strchr(&r->help_file[1], '\\')) != NULL) {
file = s;
- driver_unix_convert(conn,file,&st);
DEBUG(10,("deleting helpfile [%s]\n", s));
- unlink_internals(conn, NULL, 0, file, False);
+ driver_unlink_internals(conn, file);
}
}
/* check if we are done removing files */
- if ( info_3->dependentfiles ) {
- while ( info_3->dependentfiles[i][0] ) {
+ if (r->dependent_files) {
+ while (r->dependent_files[i] && r->dependent_files[i][0]) {
char *p;
/* bypass the "\print$" portion of the path */
- if ( (p = strchr( info_3->dependentfiles[i]+1, '\\' )) != NULL ) {
+ if ((p = strchr(r->dependent_files[i]+1, '\\')) != NULL) {
file = p;
- driver_unix_convert(conn,file,&st);
DEBUG(10,("deleting dependent file [%s]\n", file));
- unlink_internals(conn, NULL, 0, file, False);
+ driver_unlink_internals(conn, file);
}
i++;
done:
if (conn != NULL) {
vfs_ChDir(conn, oldcwd);
- conn_free_internal(conn);
+ conn_free(conn);
}
return ret;
}
***************************************************************************/
WERROR delete_printer_driver(struct pipes_struct *rpc_pipe,
- NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3,
+ const struct spoolss_DriverInfo8 *r,
uint32 version, bool delete_files )
{
char *key = NULL;
const char *arch;
TDB_DATA dbuf;
- NT_PRINTER_DRIVER_INFO_LEVEL ctr;
/* delete the tdb data first */
- arch = get_short_archi(info_3->environment);
+ arch = get_short_archi(r->architecture);
if (!arch) {
return WERR_UNKNOWN_PRINTER_DRIVER;
}
if (asprintf(&key, "%s%s/%d/%s", DRIVERS_PREFIX,
- arch, version, info_3->name) < 0) {
+ arch, version, r->driver_name) < 0) {
return WERR_NOMEM;
}
DEBUG(5,("delete_printer_driver: key = [%s] delete_files = %s\n",
key, delete_files ? "TRUE" : "FALSE" ));
- ctr.info_3 = info_3;
- dump_a_printer_driver( ctr, 3 );
-
/* check if the driver actually exists for this environment */
dbuf = tdb_fetch_bystring( tdb_drivers, key );
*/
if ( delete_files )
- delete_driver_files(rpc_pipe, info_3);
+ delete_driver_files(rpc_pipe, r);
DEBUG(5,("delete_printer_driver: driver delete successful [%s]\n", key));
SAFE_FREE(key);
Store a security desc for a printer.
****************************************************************************/
-WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr)
+WERROR nt_printing_setsec(const char *sharename, struct sec_desc_buf *secdesc_ctr)
{
- SEC_DESC_BUF *new_secdesc_ctr = NULL;
- SEC_DESC_BUF *old_secdesc_ctr = NULL;
+ struct sec_desc_buf *new_secdesc_ctr = NULL;
+ struct sec_desc_buf *old_secdesc_ctr = NULL;
TALLOC_CTX *mem_ctx = NULL;
TDB_DATA kbuf;
TDB_DATA dbuf;
descriptor then copy them over from the old one. */
if (!secdesc_ctr->sd->owner_sid || !secdesc_ctr->sd->group_sid) {
- DOM_SID *owner_sid, *group_sid;
- SEC_ACL *dacl, *sacl;
- SEC_DESC *psd = NULL;
+ struct dom_sid *owner_sid, *group_sid;
+ struct security_acl *dacl, *sacl;
+ struct security_descriptor *psd = NULL;
size_t size;
if (!nt_printing_getsec(mem_ctx, sharename, &old_secdesc_ctr)) {
Construct a default security descriptor buffer for a printer.
****************************************************************************/
-static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
+static struct sec_desc_buf *construct_default_printer_sdb(TALLOC_CTX *ctx)
{
- SEC_ACE ace[5]; /* max number of ace entries */
+ struct security_ace ace[5]; /* max number of ace entries */
int i = 0;
uint32_t sa;
- SEC_ACL *psa = NULL;
- SEC_DESC_BUF *sdb = NULL;
- SEC_DESC *psd = NULL;
- DOM_SID adm_sid;
+ struct security_acl *psa = NULL;
+ struct sec_desc_buf *sdb = NULL;
+ struct security_descriptor *psd = NULL;
+ struct dom_sid adm_sid;
size_t sd_size;
/* Create an ACE where Everyone is allowed to print */
/* Add the domain admins group if we are a DC */
if ( IS_DC ) {
- DOM_SID domadmins_sid;
+ struct dom_sid domadmins_sid;
- sid_copy(&domadmins_sid, get_global_sam_sid());
- sid_append_rid(&domadmins_sid, DOMAIN_GROUP_RID_ADMINS);
+ sid_compose(&domadmins_sid, get_global_sam_sid(),
+ DOMAIN_RID_ADMINS);
sa = PRINTER_ACE_FULL_CONTROL;
init_sec_ace(&ace[i++], &domadmins_sid,
sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
}
else if (secrets_fetch_domain_sid(lp_workgroup(), &adm_sid)) {
- sid_append_rid(&adm_sid, DOMAIN_USER_RID_ADMIN);
+ sid_append_rid(&adm_sid, DOMAIN_RID_ADMINISTRATOR);
sa = PRINTER_ACE_FULL_CONTROL;
init_sec_ace(&ace[i++], &adm_sid,
NT5 machine. */
if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) != NULL) {
- psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
+ psd = make_sec_desc(ctx, SD_REVISION, SEC_DESC_SELF_RELATIVE,
&global_sid_Builtin_Administrators,
&global_sid_Builtin_Administrators,
NULL, psa, &sd_size);
Get a security desc for a printer.
****************************************************************************/
-bool nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, SEC_DESC_BUF **secdesc_ctr)
+bool nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, struct sec_desc_buf **secdesc_ctr)
{
TDB_DATA kbuf;
TDB_DATA dbuf;
down. Take ownership of security descriptor. */
if (sid_equal((*secdesc_ctr)->sd->owner_sid, &global_sid_World)) {
- DOM_SID owner_sid;
+ struct dom_sid owner_sid;
/* Change sd owner to workgroup administrator */
if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid)) {
- SEC_DESC_BUF *new_secdesc_ctr = NULL;
- SEC_DESC *psd = NULL;
+ struct sec_desc_buf *new_secdesc_ctr = NULL;
+ struct security_descriptor *psd = NULL;
size_t size;
/* Create new sd */
- sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
+ sid_append_rid(&owner_sid, DOMAIN_RID_ADMINISTRATOR);
psd = make_sec_desc(ctx, (*secdesc_ctr)->sd->revision, (*secdesc_ctr)->sd->type,
&owner_sid,
}
if (DEBUGLEVEL >= 10) {
- SEC_ACL *the_acl = (*secdesc_ctr)->sd->dacl;
+ struct security_acl *the_acl = (*secdesc_ctr)->sd->dacl;
int i;
DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
It turns out that NT4 security descriptors use generic access rights and
NT5 the object specific ones. */
-void map_printer_permissions(SEC_DESC *sd)
+void map_printer_permissions(struct security_descriptor *sd)
{
int i;
}
}
-void map_job_permissions(SEC_DESC *sd)
+void map_job_permissions(struct security_descriptor *sd)
{
int i;
print_queue_purge
Try access control in the following order (for performance reasons):
- 1) root ans SE_PRINT_OPERATOR can do anything (easy check)
+ 1) root and SE_PRINT_OPERATOR can do anything (easy check)
2) check security descriptor (bit comparisons in memory)
3) "printer admins" (may result in numerous calls to winbind)
bool print_access_check(struct auth_serversupplied_info *server_info, int snum,
int access_type)
{
- SEC_DESC_BUF *secdesc = NULL;
+ struct sec_desc_buf *secdesc = NULL;
uint32 access_granted;
NTSTATUS status;
const char *pname;
/* Always allow root or SE_PRINT_OPERATROR to do anything */
- if (server_info->utok.uid == 0
+ if (server_info->utok.uid == sec_initial_uid()
|| user_has_privileges(server_info->ptok, &se_printop ) ) {
return True;
}
}
if (access_type == JOB_ACCESS_ADMINISTER) {
- SEC_DESC_BUF *parent_secdesc = secdesc;
+ struct sec_desc_buf *parent_secdesc = secdesc;
/* Create a child security descriptor to check permissions
against. This is because print jobs are child objects
/* see if we need to try the printer admin list */
- if ((access_granted == 0) &&
+ if (!NT_STATUS_IS_OK(status) &&
(token_contains_name_in_list(uidtoname(server_info->utok.uid),
NULL, NULL, server_info->ptok,
lp_printer_admin(snum)))) {