*/
#include "includes.h"
-#include "librpc/gen_ndr/messaging.h"
-#include "printing/pcap.h"
#include "printing/nt_printing_tdb.h"
-#include "registry.h"
-#include "registry/reg_objects.h"
-#include "../librpc/gen_ndr/ndr_security.h"
-#include "rpc_server/srv_spoolss_util.h"
-
-#include "../rpc_server/srv_spoolss_util.h"
+#include "../librpc/gen_ndr/ndr_spoolss.h"
+#include "rpc_server/spoolss/srv_spoolss_util.h"
+#include "nt_printing.h"
+#include "secrets.h"
+#include "../librpc/gen_ndr/netlogon.h"
+#include "../libcli/security/security.h"
+#include "passdb/machine_sid.h"
+#include "smbd/smbd.h"
+#include "smbd/globals.h"
+#include "auth.h"
+#include "messages.h"
+#include "rpc_server/spoolss/srv_spoolss_nt.h"
+#include "rpc_client/cli_winreg_spoolss.h"
/* Map generic permissions to printer object specific permissions */
PRINTER_ALL_ACCESS
};
-const struct standard_mapping printer_std_mapping = {
- PRINTER_READ,
- PRINTER_WRITE,
- PRINTER_EXECUTE,
- PRINTER_ALL_ACCESS
-};
-
/* Map generic permissions to print server object specific permissions */
const struct generic_mapping printserver_generic_mapping = {
SERVER_ALL_ACCESS
};
-const struct generic_mapping printserver_std_mapping = {
- SERVER_READ,
- SERVER_WRITE,
- SERVER_EXECUTE,
- SERVER_ALL_ACCESS
-};
-
/* Map generic permissions to job object specific permissions */
const struct generic_mapping job_generic_mapping = {
{NULL, "", -1 }
};
+static bool print_driver_directories_init(void)
+{
+ int service, i;
+ char *driver_path;
+ bool ok;
+ TALLOC_CTX *mem_ctx = talloc_stackframe();
+
+ service = lp_servicenumber("print$");
+ if (service < 0) {
+ /* We don't have a print$ share */
+ DEBUG(5, ("No print$ share has been configured.\n"));
+ talloc_free(mem_ctx);
+ return true;
+ }
+
+ driver_path = lp_path(mem_ctx, service);
+ if (driver_path == NULL) {
+ talloc_free(mem_ctx);
+ return false;
+ }
+
+ ok = directory_create_or_exist(driver_path, sec_initial_uid(), 0755);
+ if (!ok) {
+ DEBUG(1, ("Failed to create printer driver directory %s\n",
+ driver_path));
+ talloc_free(mem_ctx);
+ return false;
+ }
+
+ for (i = 0; archi_table[i].long_archi != NULL; i++) {
+ const char *arch_path;
+
+ arch_path = talloc_asprintf(mem_ctx,
+ "%s/%s",
+ driver_path,
+ archi_table[i].short_archi);
+ if (arch_path == NULL) {
+ talloc_free(mem_ctx);
+ return false;
+ }
+
+ ok = directory_create_or_exist(arch_path,
+ sec_initial_uid(),
+ 0755);
+ if (!ok) {
+ DEBUG(1, ("Failed to create printer driver "
+ "architecture directory %s\n",
+ arch_path));
+ talloc_free(mem_ctx);
+ return false;
+ }
+ }
+
+ talloc_free(mem_ctx);
+ return true;
+}
+
+/****************************************************************************
+ Forward a MSG_PRINTER_DRVUPGRADE message from another smbd to the
+ background lpq updater.
+****************************************************************************/
+
+static void forward_drv_upgrade_printer_msg(struct messaging_context *msg,
+ void *private_data,
+ uint32_t msg_type,
+ struct server_id server_id,
+ DATA_BLOB *data)
+{
+ extern pid_t background_lpq_updater_pid;
+
+ if (background_lpq_updater_pid == -1) {
+ DEBUG(3,("no background lpq queue updater\n"));
+ return;
+ }
+
+ messaging_send_buf(msg,
+ pid_to_procid(background_lpq_updater_pid),
+ MSG_PRINTER_DRVUPGRADE,
+ data->data,
+ data->length);
+}
+
/****************************************************************************
Open the NT printing tdbs. Done once before fork().
****************************************************************************/
{
WERROR win_rc;
+ if (!print_driver_directories_init()) {
+ return false;
+ }
+
if (!nt_printing_tdb_upgrade()) {
return false;
}
/*
* register callback to handle updating printers as new
- * drivers are installed
+ * drivers are installed. Forwards to background lpq updater.
*/
messaging_register(msg_ctx, NULL, MSG_PRINTER_DRVUPGRADE,
- do_drv_upgrade_printer);
+ forward_drv_upgrade_printer_msg);
/* 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 serverid_register() */
if ( lp_security() == SEC_ADS ) {
- win_rc = check_published_printers();
+ win_rc = check_published_printers(msg_ctx);
if (!W_ERROR_IS_OK(win_rc))
DEBUG(0, ("nt_printing_init: error checking published printers: %s\n", win_errstr(win_rc)));
}
{
int i=-1;
- DEBUG(107,("Getting architecture dependant directory\n"));
+ DEBUG(107,("Getting architecture dependent directory\n"));
do {
i++;
} while ( (archi_table[i].long_archi!=NULL ) &&
- StrCaseCmp(long_archi, archi_table[i].long_archi) );
+ strcasecmp_m(long_archi, archi_table[i].long_archi) );
if (archi_table[i].long_archi==NULL) {
DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi));
}
/* Skip OEM header (if any) and the DOS stub to start of Windows header */
- if (SMB_VFS_LSEEK(fsp, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
+ if (SMB_VFS_LSEEK(fsp, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (off_t)-1) {
DEBUG(3,("get_file_version: File [%s] too short, errno = %d\n",
fname, errno));
/* Assume this isn't an error... the file just looks sort of like a PE/NE file */
/* Just skip over optional header to get to section table */
if (SMB_VFS_LSEEK(fsp,
SVAL(buf,PE_HEADER_OPTIONAL_HEADER_SIZE)-(NE_HEADER_SIZE-PE_HEADER_SIZE),
- SEEK_CUR) == (SMB_OFF_T)-1) {
+ SEEK_CUR) == (off_t)-1) {
DEBUG(3,("get_file_version: File [%s] Windows optional header too short, errno = %d\n",
fname, errno));
goto error_exit;
}
/* Seek to the start of the .rsrc section info */
- if (SMB_VFS_LSEEK(fsp, section_pos, SEEK_SET) == (SMB_OFF_T)-1) {
+ if (SMB_VFS_LSEEK(fsp, section_pos, SEEK_SET) == (off_t)-1) {
DEBUG(3,("get_file_version: PE file [%s] too short for section info, errno = %d\n",
fname, errno));
goto error_exit;
/****************************************************************************
Determine the correct cVersion associated with an architecture and driver
****************************************************************************/
-static uint32 get_correct_cversion(struct pipes_struct *p,
+static uint32 get_correct_cversion(struct auth_session_info *session_info,
const char *architecture,
const char *driverpath_in,
WERROR *perr)
{
- int cversion;
+ int cversion = -1;
NTSTATUS nt_status;
struct smb_filename *smb_fname = NULL;
char *driverpath = NULL;
files_struct *fsp = NULL;
connection_struct *conn = NULL;
- NTSTATUS status;
char *oldcwd;
- fstring printdollar;
+ char *printdollar = NULL;
int printdollar_snum;
*perr = WERR_INVALID_PARAM;
return 3;
}
- fstrcpy(printdollar, "print$");
-
- printdollar_snum = find_service(printdollar);
+ printdollar_snum = find_service(talloc_tos(), "print$", &printdollar);
+ if (!printdollar) {
+ *perr = WERR_NOMEM;
+ return -1;
+ }
if (printdollar_snum == -1) {
*perr = WERR_NO_SUCH_SHARE;
return -1;
}
- nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum,
- lp_pathname(printdollar_snum),
- p->server_info, &oldcwd);
+ nt_status = create_conn_struct_cwd(talloc_tos(),
+ server_event_context(),
+ server_messaging_context(),
+ &conn,
+ printdollar_snum,
+ lp_path(talloc_tos(), printdollar_snum),
+ session_info, &oldcwd);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0,("get_correct_cversion: create_conn_struct "
"returned %s\n", nt_errstr(nt_status)));
return -1;
}
+ nt_status = set_conn_force_user_group(conn, printdollar_snum);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(0, ("failed set force user / group\n"));
+ *perr = ntstatus_to_werror(nt_status);
+ goto error_free_conn;
+ }
+
+ if (!become_user_by_session(conn, session_info)) {
+ DEBUG(0, ("failed to become user\n"));
+ *perr = WERR_ACCESS_DENIED;
+ goto error_free_conn;
+ }
+
/* Open the driver file (Portable Executable format) and determine the
* deriver the cversion. */
driverpath = talloc_asprintf(talloc_tos(),
nt_status = vfs_file_exist(conn, smb_fname);
if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(3,("get_correct_cversion: vfs_file_exist failed\n"));
*perr = WERR_BADFILE;
goto error_exit;
}
- status = SMB_VFS_CREATE_FILE(
+ nt_status = SMB_VFS_CREATE_FILE(
conn, /* conn */
NULL, /* req */
0, /* root_dir_fid */
&fsp, /* result */
NULL); /* pinfo */
- if (!NT_STATUS_IS_OK(status)) {
+ if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = "
"%d\n", smb_fname_str_dbg(smb_fname), errno));
*perr = WERR_ACCESS_DENIED;
int ret;
ret = get_file_version(fsp, smb_fname->base_name, &major, &minor);
- if (ret == -1) goto error_exit;
-
- if (!ret) {
+ if (ret == -1) {
+ *perr = WERR_INVALID_PARAM;
+ goto error_exit;
+ } else if (!ret) {
DEBUG(6,("get_correct_cversion: Version info not "
"found [%s]\n",
smb_fname_str_dbg(smb_fname)));
+ *perr = WERR_INVALID_PARAM;
goto error_exit;
}
DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
smb_fname_str_dbg(smb_fname), cversion));
-
- goto done;
+ *perr = WERR_OK;
error_exit:
- cversion = -1;
- done:
+ unbecome_user();
+ error_free_conn:
TALLOC_FREE(smb_fname);
if (fsp != NULL) {
close_file(NULL, fsp, NORMAL_CLOSE);
}
if (conn != NULL) {
vfs_ChDir(conn, oldcwd);
+ SMB_VFS_DISCONNECT(conn);
conn_free(conn);
}
- if (cversion != -1) {
- *perr = WERR_OK;
+ if (!W_ERROR_IS_OK(*perr)) {
+ cversion = -1;
}
+
return cversion;
}
} while (0);
static WERROR clean_up_driver_struct_level(TALLOC_CTX *mem_ctx,
- struct pipes_struct *rpc_pipe,
+ struct auth_session_info *session_info,
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)
+ enum spoolss_DriverOSVersion *version)
{
const char *short_architecture;
int i;
WERROR err;
char *_p;
- if (!*driver_path || !*data_file || !*config_file) {
+ if (!*driver_path || !*data_file) {
+ return WERR_INVALID_PARAM;
+ }
+
+ if (!strequal(architecture, SPOOLSS_ARCHITECTURE_4_0) && !*config_file) {
return WERR_INVALID_PARAM;
}
strip_driver_path(mem_ctx, *driver_path);
strip_driver_path(mem_ctx, *data_file);
- strip_driver_path(mem_ctx, *config_file);
+ if (*config_file) {
+ strip_driver_path(mem_ctx, *config_file);
+ }
if (help_file) {
strip_driver_path(mem_ctx, *help_file);
}
* NT2K: cversion=3
*/
- *version = get_correct_cversion(rpc_pipe, short_architecture,
+ *version = get_correct_cversion(session_info, short_architecture,
*driver_path, &err);
if (*version == -1) {
return err;
****************************************************************************/
WERROR clean_up_driver_struct(TALLOC_CTX *mem_ctx,
- struct pipes_struct *rpc_pipe,
+ struct auth_session_info *session_info,
struct spoolss_AddDriverInfoCtr *r)
{
switch (r->level) {
case 3:
- return clean_up_driver_struct_level(mem_ctx, rpc_pipe,
+ return clean_up_driver_struct_level(mem_ctx, session_info,
r->info.info3->architecture,
&r->info.info3->driver_path,
&r->info.info3->data_file,
r->info.info3->dependent_files,
&r->info.info3->version);
case 6:
- return clean_up_driver_struct_level(mem_ctx, rpc_pipe,
+ return clean_up_driver_struct_level(mem_ctx, session_info,
r->info.info6->architecture,
&r->info.info6->driver_path,
&r->info.info6->data_file,
}
/* Setup a synthetic smb_filename struct */
- smb_fname_new = TALLOC_ZERO_P(mem_ctx, struct smb_filename);
+ smb_fname_new = talloc_zero(mem_ctx, struct smb_filename);
if (!smb_fname_new) {
ret = WERR_NOMEM;
goto out;
return ret;
}
-WERROR move_driver_to_download_area(struct pipes_struct *p,
- struct spoolss_AddDriverInfoCtr *r,
- WERROR *perr)
+WERROR move_driver_to_download_area(struct auth_session_info *session_info,
+ struct spoolss_AddDriverInfoCtr *r)
{
struct spoolss_AddDriverInfo3 *driver;
struct spoolss_AddDriverInfo3 converted_driver;
TALLOC_CTX *ctx = talloc_tos();
int ver = 0;
char *oldcwd;
- fstring printdollar;
+ char *printdollar = NULL;
int printdollar_snum;
-
- *perr = WERR_OK;
+ WERROR err = WERR_OK;
switch (r->level) {
case 3:
return WERR_UNKNOWN_PRINTER_DRIVER;
}
- fstrcpy(printdollar, "print$");
-
- printdollar_snum = find_service(printdollar);
+ printdollar_snum = find_service(ctx, "print$", &printdollar);
+ if (!printdollar) {
+ return WERR_NOMEM;
+ }
if (printdollar_snum == -1) {
- *perr = WERR_NO_SUCH_SHARE;
return WERR_NO_SUCH_SHARE;
}
- nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum,
- lp_pathname(printdollar_snum),
- p->server_info, &oldcwd);
+ nt_status = create_conn_struct_cwd(talloc_tos(),
+ server_event_context(),
+ server_messaging_context(),
+ &conn,
+ printdollar_snum,
+ lp_path(talloc_tos(), printdollar_snum),
+ session_info, &oldcwd);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0,("move_driver_to_download_area: create_conn_struct "
"returned %s\n", nt_errstr(nt_status)));
- *perr = ntstatus_to_werror(nt_status);
- return *perr;
+ err = ntstatus_to_werror(nt_status);
+ return err;
+ }
+
+ nt_status = set_conn_force_user_group(conn, printdollar_snum);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(0, ("failed set force user / group\n"));
+ err = ntstatus_to_werror(nt_status);
+ goto err_free_conn;
+ }
+
+ if (!become_user_by_session(conn, session_info)) {
+ DEBUG(0, ("failed to become user\n"));
+ err = WERR_ACCESS_DENIED;
+ goto err_free_conn;
}
new_dir = talloc_asprintf(ctx,
short_architecture,
driver->version);
if (!new_dir) {
- *perr = WERR_NOMEM;
+ err = WERR_NOMEM;
goto err_exit;
}
nt_status = driver_unix_convert(conn, new_dir, &smb_dname);
if (!NT_STATUS_IS_OK(nt_status)) {
- *perr = WERR_NOMEM;
+ err = WERR_NOMEM;
goto err_exit;
}
DEBUG(5,("Creating first directory: %s\n", smb_dname->base_name));
- create_directory(conn, NULL, smb_dname);
+ nt_status = create_directory(conn, NULL, smb_dname);
+ if (!NT_STATUS_IS_OK(nt_status)
+ && !NT_STATUS_EQUAL(nt_status, NT_STATUS_OBJECT_NAME_COLLISION)) {
+ DEBUG(0, ("failed to create driver destination directory: %s\n",
+ nt_errstr(nt_status)));
+ err = ntstatus_to_werror(nt_status);
+ goto err_exit;
+ }
/* 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:
if (driver->driver_path && strlen(driver->driver_path)) {
- *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;
- }
+ err = move_driver_file_to_download_area(ctx,
+ conn,
+ driver->driver_path,
+ short_architecture,
+ driver->version,
+ ver);
+ if (!W_ERROR_IS_OK(err)) {
goto err_exit;
}
}
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;
- }
+ err = move_driver_file_to_download_area(ctx,
+ conn,
+ driver->data_file,
+ short_architecture,
+ driver->version,
+ ver);
+ if (!W_ERROR_IS_OK(err)) {
goto err_exit;
}
}
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;
- }
+ err = move_driver_file_to_download_area(ctx,
+ conn,
+ driver->config_file,
+ short_architecture,
+ driver->version,
+ ver);
+ if (!W_ERROR_IS_OK(err)) {
goto err_exit;
}
}
!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;
- }
+ err = move_driver_file_to_download_area(ctx,
+ conn,
+ driver->help_file,
+ short_architecture,
+ driver->version,
+ ver);
+ if (!W_ERROR_IS_OK(err)) {
goto err_exit;
}
}
}
}
- *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;
- }
+ err = move_driver_file_to_download_area(ctx,
+ conn,
+ driver->dependent_files->string[i],
+ short_architecture,
+ driver->version,
+ ver);
+ if (!W_ERROR_IS_OK(err)) {
goto err_exit;
}
}
}
}
- err_exit:
+ err = WERR_OK;
+ err_exit:
+ unbecome_user();
+ err_free_conn:
TALLOC_FREE(smb_dname);
if (conn != NULL) {
vfs_ChDir(conn, oldcwd);
+ SMB_VFS_DISCONNECT(conn);
conn_free(conn);
}
- if (W_ERROR_EQUAL(*perr, WERR_OK)) {
- return WERR_OK;
- }
- if (ver == -1) {
- return WERR_UNKNOWN_PRINTER_DRIVER;
- }
- return (*perr);
-}
-
-/****************************************************************************
-****************************************************************************/
-int pack_devicemode(struct spoolss_DeviceMode *devmode, uint8 *buf, int buflen)
-{
- enum ndr_err_code ndr_err;
- DATA_BLOB blob;
- int len = 0;
-
- if (devmode) {
- ndr_err = ndr_push_struct_blob(&blob, talloc_tos(),
- devmode,
- (ndr_push_flags_fn_t)
- ndr_push_spoolss_DeviceMode);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- DEBUG(10, ("pack_devicemode: "
- "error encoding spoolss_DeviceMode\n"));
- goto done;
- }
- } else {
- ZERO_STRUCT(blob);
- }
-
- len = tdb_pack(buf, buflen, "B", blob.length, blob.data);
-
- if (devmode) {
- DEBUG(8, ("Packed devicemode [%s]\n", devmode->formname));
- }
-
-done:
- return len;
-}
-
-/****************************************************************************
-****************************************************************************/
-int unpack_devicemode(TALLOC_CTX *mem_ctx,
- const uint8 *buf, int buflen,
- struct spoolss_DeviceMode **devmode)
-{
- struct spoolss_DeviceMode *dm;
- enum ndr_err_code ndr_err;
- char *data = NULL;
- int data_len = 0;
- DATA_BLOB blob;
- int len = 0;
-
- *devmode = NULL;
-
- len = tdb_unpack(buf, buflen, "B", &data_len, &data);
- if (!data) {
- return len;
- }
-
- dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
- if (!dm) {
- goto done;
- }
-
- blob = data_blob_const(data, data_len);
-
- ndr_err = ndr_pull_struct_blob(&blob, dm, dm,
- (ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- DEBUG(10, ("unpack_devicemode: "
- "error parsing spoolss_DeviceMode\n"));
- goto done;
- }
-
- DEBUG(8, ("Unpacked devicemode [%s](%s)\n",
- dm->devicename, dm->formname));
- if (dm->driverextra_data.data) {
- DEBUG(8, ("with a private section of %d bytes\n",
- dm->__driverextra_length));
- }
-
- *devmode = dm;
-
-done:
- SAFE_FREE(data);
- return len;
-}
-
-/****************************************************************************
- 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[7]; /* 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);
-
- /* add BUILTIN\Print Operators as FULL CONTROL */
-
- sa = PRINTER_ACE_FULL_CONTROL;
- init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
- SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
- SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
- init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
- 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;
-}
-
-#ifdef HAVE_ADS
-/*****************************************************************
- ****************************************************************/
-
-static void store_printer_guid(const char *printer, struct GUID guid)
-{
- TALLOC_CTX *tmp_ctx;
- struct auth_serversupplied_info *server_info = NULL;
- const char *guid_str;
- DATA_BLOB blob;
- NTSTATUS status;
- WERROR result;
-
- tmp_ctx = talloc_new(NULL);
- if (!tmp_ctx) {
- DEBUG(0, ("store_printer_guid: Out of memory?!\n"));
- return;
- }
-
- status = make_server_info_system(tmp_ctx, &server_info);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("store_printer_guid: "
- "Could not create system server_info\n"));
- goto done;
- }
-
- guid_str = GUID_string(tmp_ctx, &guid);
- if (!guid_str) {
- DEBUG(0, ("store_printer_guid: Out of memory?!\n"));
- goto done;
- }
-
- /* We used to store this as a REG_BINARY but that causes
- Vista to whine */
-
- if (!push_reg_sz(tmp_ctx, &blob, guid_str)) {
- DEBUG(0, ("store_printer_guid: "
- "Could not marshall string %s for objectGUID\n",
- guid_str));
- goto done;
- }
-
- result = winreg_set_printer_dataex(tmp_ctx, server_info, printer,
- SPOOL_DSSPOOLER_KEY, "objectGUID",
- REG_SZ, blob.data, blob.length);
- if (!W_ERROR_IS_OK(result)) {
- DEBUG(0, ("store_printer_guid: "
- "Failed to store GUID for printer %s\n", printer));
- }
-
-done:
- talloc_free(tmp_ctx);
-}
-
-static WERROR nt_printer_publish_ads(ADS_STRUCT *ads,
- struct spoolss_PrinterInfo2 *pinfo2)
-{
- ADS_STATUS ads_rc;
- LDAPMessage *res;
- char *prt_dn = NULL, *srv_dn, *srv_cn_0, *srv_cn_escaped, *sharename_escaped;
- char *srv_dn_utf8, **srv_cn_utf8;
- TALLOC_CTX *ctx;
- ADS_MODLIST mods;
- const char *attrs[] = {"objectGUID", NULL};
- struct GUID guid;
- WERROR win_rc = WERR_OK;
- size_t converted_size;
- const char *printer = pinfo2->sharename;
-
- /* build the ads mods */
- ctx = talloc_init("nt_printer_publish_ads");
- if (ctx == NULL) {
- return WERR_NOMEM;
- }
-
- DEBUG(5, ("publishing printer %s\n", printer));
-
- /* figure out where to publish */
- ads_find_machine_acct(ads, &res, global_myname());
-
- /* We use ldap_get_dn here as we need the answer
- * in utf8 to call ldap_explode_dn(). JRA. */
-
- 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_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_talloc(ctx, &srv_cn_0, srv_cn_utf8[0], &converted_size)) {
- TALLOC_FREE(ctx);
- ldap_memfree(srv_dn_utf8);
- ldap_memfree(srv_cn_utf8);
- TALLOC_FREE(srv_dn);
- return WERR_SERVER_UNAVAILABLE;
- }
-
- ldap_memfree(srv_dn_utf8);
- ldap_memfree(srv_cn_utf8);
-
- srv_cn_escaped = escape_rdn_val_string_alloc(srv_cn_0);
- if (!srv_cn_escaped) {
- TALLOC_FREE(ctx);
- return WERR_SERVER_UNAVAILABLE;
- }
- sharename_escaped = escape_rdn_val_string_alloc(printer);
- if (!sharename_escaped) {
- SAFE_FREE(srv_cn_escaped);
- TALLOC_FREE(ctx);
- return WERR_SERVER_UNAVAILABLE;
- }
-
- prt_dn = talloc_asprintf(ctx, "cn=%s-%s,%s", srv_cn_escaped, sharename_escaped, srv_dn);
-
- SAFE_FREE(srv_cn_escaped);
- SAFE_FREE(sharename_escaped);
-
- mods = ads_init_mods(ctx);
-
- if (mods == NULL) {
- SAFE_FREE(prt_dn);
- TALLOC_FREE(ctx);
- return WERR_NOMEM;
- }
-
- ads_mod_str(ctx, &mods, SPOOL_REG_PRINTERNAME, printer);
-
- /* publish it */
- ads_rc = ads_mod_printer_entry(ads, prt_dn, ctx, &mods);
- if (ads_rc.err.rc == LDAP_NO_SUCH_OBJECT) {
- int i;
- for (i=0; mods[i] != 0; i++)
- ;
- mods[i] = (LDAPMod *)-1;
- ads_rc = ads_add_printer_entry(ads, prt_dn, ctx, &mods);
- }
-
- if (!ADS_ERR_OK(ads_rc)) {
- DEBUG(3, ("error publishing %s: %s\n",
- printer, ads_errstr(ads_rc)));
- }
-
- /* retreive the guid and store it locally */
- if (ADS_ERR_OK(ads_search_dn(ads, &res, prt_dn, attrs))) {
- ZERO_STRUCT(guid);
- ads_pull_guid(ads, res, &guid);
- ads_msgfree(ads, res);
- store_printer_guid(printer, guid);
- }
- TALLOC_FREE(ctx);
-
- return win_rc;
-}
-
-static WERROR nt_printer_unpublish_ads(ADS_STRUCT *ads,
- const char *printer)
-{
- ADS_STATUS ads_rc;
- LDAPMessage *res = NULL;
- char *prt_dn = NULL;
-
- DEBUG(5, ("unpublishing printer %s\n", printer));
-
- /* remove the printer from the directory */
- ads_rc = ads_find_printer_on_server(ads, &res,
- printer, global_myname());
-
- if (ADS_ERR_OK(ads_rc) && res && ads_count_replies(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);
- TALLOC_FREE(prt_dn);
- }
-
- if (res) {
- ads_msgfree(ads, res);
- }
- return WERR_OK;
+ return err;
}
-/****************************************************************************
- * Publish a printer in the directory
- *
- * @param mem_ctx memory context
- * @param server_info server_info to access winreg pipe
- * @param pinfo2 printer information
- * @param action publish/unpublish action
- * @return WERROR indicating status of publishing
- ***************************************************************************/
-
-WERROR nt_printer_publish(TALLOC_CTX *mem_ctx,
- struct auth_serversupplied_info *server_info,
- struct spoolss_PrinterInfo2 *pinfo2,
- int action)
-{
- uint32_t info2_mask = SPOOLSS_PRINTER_INFO_ATTRIBUTES;
- struct spoolss_SetPrinterInfo2 *sinfo2;
- ADS_STATUS ads_rc;
- ADS_STRUCT *ads = NULL;
- WERROR win_rc;
-
- sinfo2 = talloc_zero(mem_ctx, struct spoolss_SetPrinterInfo2);
- if (!sinfo2) {
- return WERR_NOMEM;
- }
-
- switch (action) {
- case DSPRINT_PUBLISH:
- case DSPRINT_UPDATE:
- pinfo2->attributes |= PRINTER_ATTRIBUTE_PUBLISHED;
- break;
- case DSPRINT_UNPUBLISH:
- pinfo2->attributes ^= PRINTER_ATTRIBUTE_PUBLISHED;
- break;
- default:
- win_rc = WERR_NOT_SUPPORTED;
- goto done;
- }
-
- sinfo2->attributes = pinfo2->attributes;
-
- win_rc = winreg_update_printer(mem_ctx, server_info,
- pinfo2->sharename, info2_mask,
- sinfo2, NULL, NULL);
- if (!W_ERROR_IS_OK(win_rc)) {
- DEBUG(3, ("err %d saving data\n", W_ERROR_V(win_rc)));
- goto done;
- }
-
- TALLOC_FREE(sinfo2);
-
- ads = ads_init(lp_realm(), lp_workgroup(), NULL);
- if (!ads) {
- DEBUG(3, ("ads_init() failed\n"));
- win_rc = WERR_SERVER_UNAVAILABLE;
- goto done;
- }
- setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
- SAFE_FREE(ads->auth.password);
- ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
- NULL, NULL);
-
- /* ads_connect() will find the DC for us */
- ads_rc = ads_connect(ads);
- if (!ADS_ERR_OK(ads_rc)) {
- DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
- win_rc = WERR_ACCESS_DENIED;
- goto done;
- }
-
- switch (action) {
- case DSPRINT_PUBLISH:
- case DSPRINT_UPDATE:
- win_rc = nt_printer_publish_ads(ads, pinfo2);
- break;
- case DSPRINT_UNPUBLISH:
- win_rc = nt_printer_unpublish_ads(ads, pinfo2->sharename);
- break;
- }
-
-done:
- ads_destroy(&ads);
- return win_rc;
-}
-
-WERROR check_published_printers(void)
-{
- ADS_STATUS ads_rc;
- ADS_STRUCT *ads = NULL;
- int snum;
- int n_services = lp_numservices();
- TALLOC_CTX *tmp_ctx = NULL;
- struct auth_serversupplied_info *server_info = NULL;
- struct spoolss_PrinterInfo2 *pinfo2;
- NTSTATUS status;
- WERROR result;
-
- tmp_ctx = talloc_new(NULL);
- if (!tmp_ctx) return WERR_NOMEM;
-
- ads = ads_init(lp_realm(), lp_workgroup(), NULL);
- if (!ads) {
- DEBUG(3, ("ads_init() failed\n"));
- return WERR_SERVER_UNAVAILABLE;
- }
- setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
- SAFE_FREE(ads->auth.password);
- ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
- NULL, NULL);
-
- /* ads_connect() will find the DC for us */
- ads_rc = ads_connect(ads);
- if (!ADS_ERR_OK(ads_rc)) {
- DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
- result = WERR_ACCESS_DENIED;
- goto done;
- }
-
- status = make_server_info_system(tmp_ctx, &server_info);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("check_published_printers: "
- "Could not create system server_info\n"));
- result = WERR_ACCESS_DENIED;
- goto done;
- }
-
- for (snum = 0; snum < n_services; snum++) {
- if (!lp_snum_ok(snum) || !lp_print_ok(snum)) {
- continue;
- }
-
- result = winreg_get_printer(tmp_ctx, server_info, NULL,
- lp_servicename(snum), &pinfo2);
- if (!W_ERROR_IS_OK(result)) {
- continue;
- }
-
- if (pinfo2->attributes & PRINTER_ATTRIBUTE_PUBLISHED) {
- nt_printer_publish_ads(ads, pinfo2);
- }
-
- TALLOC_FREE(pinfo2);
- }
-
- result = WERR_OK;
-done:
- ads_destroy(&ads);
- ads_kdestroy("MEMORY:prtpub_cache");
- talloc_free(tmp_ctx);
- return result;
-}
-
-bool is_printer_published(TALLOC_CTX *mem_ctx,
- struct auth_serversupplied_info *server_info,
- char *servername, char *printer, struct GUID *guid,
- struct spoolss_PrinterInfo2 **info2)
-{
- struct spoolss_PrinterInfo2 *pinfo2 = NULL;
- enum winreg_Type type;
- uint8_t *data;
- uint32_t data_size;
- WERROR result;
- NTSTATUS status;
-
- result = winreg_get_printer(mem_ctx, server_info,
- servername, printer, &pinfo2);
- if (!W_ERROR_IS_OK(result)) {
- return false;
- }
-
- if (!(pinfo2->attributes & PRINTER_ATTRIBUTE_PUBLISHED)) {
- TALLOC_FREE(pinfo2);
- return false;
- }
-
- if (!guid) {
- goto done;
- }
-
- /* fetching printer guids really ought to be a separate function. */
-
- result = winreg_get_printer_dataex(mem_ctx, server_info, printer,
- SPOOL_DSSPOOLER_KEY, "objectGUID",
- &type, &data, &data_size);
- if (!W_ERROR_IS_OK(result)) {
- TALLOC_FREE(pinfo2);
- return false;
- }
-
- /* We used to store the guid as REG_BINARY, then swapped
- to REG_SZ for Vista compatibility so check for both */
-
- switch (type) {
- case REG_SZ:
- status = GUID_from_string((char *)data, guid);
- if (!NT_STATUS_IS_OK(status)) {
- TALLOC_FREE(pinfo2);
- return false;
- }
- break;
-
- case REG_BINARY:
- if (data_size != sizeof(struct GUID)) {
- TALLOC_FREE(pinfo2);
- return false;
- }
- memcpy(guid, data, sizeof(struct GUID));
- break;
- default:
- DEBUG(0,("is_printer_published: GUID value stored as "
- "invaluid type (%d)\n", type));
- break;
- }
-
-done:
- if (info2) {
- *info2 = talloc_move(mem_ctx, &pinfo2);
- }
- talloc_free(pinfo2);
- return true;
-}
-#else
-WERROR nt_printer_publish(TALLOC_CTX *mem_ctx,
- struct auth_serversupplied_info *server_info,
- struct spoolss_PrinterInfo2 *pinfo2,
- int action)
-{
- return WERR_OK;
-}
-
-WERROR check_published_printers(void)
-{
- return WERR_OK;
-}
-
-bool is_printer_published(TALLOC_CTX *mem_ctx,
- struct auth_serversupplied_info *server_info,
- char *servername, char *printer, struct GUID *guid,
- struct spoolss_PrinterInfo2 **info2)
-{
- return False;
-}
-#endif /* HAVE_ADS */
-
-/****************************************************************************
- ***************************************************************************/
-
-static char *win_driver;
-static char *os2_driver;
-
-static const char *get_win_driver(void)
-{
- if (win_driver == NULL) {
- return "";
- }
- return win_driver;
-}
-
-static const char *get_os2_driver(void)
-{
- if (os2_driver == NULL) {
- return "";
- }
- return os2_driver;
-}
-
-static bool set_driver_mapping(const char *from, const char *to)
-{
- SAFE_FREE(win_driver);
- SAFE_FREE(os2_driver);
-
- win_driver = SMB_STRDUP(from);
- os2_driver = SMB_STRDUP(to);
-
- if (win_driver == NULL || os2_driver == NULL) {
- SAFE_FREE(win_driver);
- SAFE_FREE(os2_driver);
- return false;
- }
- return true;
-}
-
-/**
- * @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;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-bool driver_info_ctr_to_info8(struct spoolss_AddDriverInfoCtr *r,
- struct spoolss_DriverInfo8 *_info8)
-{
- 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;
- }
-
- *_info8 = info8;
-
- return true;
-}
-
-
/****************************************************************************
Determine whether or not a particular driver is currently assigned
to a printer
****************************************************************************/
bool printer_driver_in_use(TALLOC_CTX *mem_ctx,
- struct auth_serversupplied_info *server_info,
- const struct spoolss_DriverInfo8 *r)
+ struct dcerpc_binding_handle *b,
+ const struct spoolss_DriverInfo8 *r)
{
int snum;
int n_services = lp_numservices();
/* loop through the printers.tdb and check for the drivername */
for (snum=0; snum<n_services && !in_use; snum++) {
- if (!lp_snum_ok(snum) || !lp_print_ok(snum)) {
+ if (!lp_snum_ok(snum) || !lp_printable(snum)) {
continue;
}
- result = winreg_get_printer(mem_ctx, server_info, NULL,
- lp_servicename(snum), &pinfo2);
+ result = winreg_get_printer(mem_ctx, b,
+ lp_servicename(talloc_tos(), snum),
+ &pinfo2);
if (!W_ERROR_IS_OK(result)) {
continue; /* skip */
}
DEBUG(10,("printer_driver_in_use: Completed search through ntprinters.tdb...\n"));
if ( in_use ) {
- struct spoolss_DriverInfo8 *driver;
+ struct spoolss_DriverInfo8 *driver = NULL;
WERROR werr;
DEBUG(5,("printer_driver_in_use: driver \"%s\" is currently in use\n", r->driver_name));
"Windows NT x86" version 2 or 3 left */
if (!strequal("Windows NT x86", r->architecture)) {
- werr = winreg_get_driver(mem_ctx, server_info,
+ werr = winreg_get_driver(mem_ctx, b,
"Windows NT x86",
r->driver_name,
DRIVER_ANY_VERSION,
&driver);
} else if (r->version == 2) {
- werr = winreg_get_driver(mem_ctx, server_info,
+ werr = winreg_get_driver(mem_ctx, b,
"Windows NT x86",
r->driver_name,
3, &driver);
} else if (r->version == 3) {
- werr = winreg_get_driver(mem_ctx, server_info,
+ werr = winreg_get_driver(mem_ctx, b,
"Windows NT x86",
r->driver_name,
2, &driver);
****************************************************************************/
bool printer_driver_files_in_use(TALLOC_CTX *mem_ctx,
- struct auth_serversupplied_info *server_info,
+ struct dcerpc_binding_handle *b,
struct spoolss_DriverInfo8 *info)
{
int i;
/* get the list of drivers */
- result = winreg_get_driver_list(mem_ctx, server_info,
+ result = winreg_get_driver_list(mem_ctx, b,
info->architecture, version,
&num_drivers, &drivers);
if (!W_ERROR_IS_OK(result)) {
driver = NULL;
- result = winreg_get_driver(mem_ctx, server_info,
+ result = winreg_get_driver(mem_ctx, b,
info->architecture, drivers[i],
version, &driver);
if (!W_ERROR_IS_OK(result)) {
}
static NTSTATUS driver_unlink_internals(connection_struct *conn,
- const char *name)
+ const char *short_arch,
+ int vers,
+ const char *fname)
{
+ TALLOC_CTX *tmp_ctx = talloc_new(conn);
struct smb_filename *smb_fname = NULL;
- NTSTATUS status;
+ char *print_dlr_path;
+ NTSTATUS status = NT_STATUS_NO_MEMORY;
- status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL,
- &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
+ print_dlr_path = talloc_asprintf(tmp_ctx, "%s/%d/%s",
+ short_arch, vers, fname);
+ if (print_dlr_path == NULL) {
+ goto err_out;
}
- status = unlink_internals(conn, NULL, 0, smb_fname, false);
+ smb_fname = synthetic_smb_fname(tmp_ctx, print_dlr_path, NULL, NULL);
+ if (smb_fname == NULL) {
+ goto err_out;
+ }
- TALLOC_FREE(smb_fname);
+ status = unlink_internals(conn, NULL, 0, smb_fname, false);
+err_out:
+ talloc_free(tmp_ctx);
return status;
}
this.
****************************************************************************/
-bool delete_driver_files(struct auth_serversupplied_info *server_info,
+bool delete_driver_files(const struct auth_session_info *session_info,
const struct spoolss_DriverInfo8 *r)
{
- int i = 0;
- char *s;
- const char *file;
+ const char *short_arch;
connection_struct *conn;
NTSTATUS nt_status;
char *oldcwd;
- fstring printdollar;
+ char *printdollar = NULL;
int printdollar_snum;
bool ret = false;
DEBUG(6,("delete_driver_files: deleting driver [%s] - version [%d]\n",
r->driver_name, r->version));
- fstrcpy(printdollar, "print$");
-
- printdollar_snum = find_service(printdollar);
+ printdollar_snum = find_service(talloc_tos(), "print$", &printdollar);
+ if (!printdollar) {
+ return false;
+ }
if (printdollar_snum == -1) {
return false;
}
- nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum,
- lp_pathname(printdollar_snum),
- server_info, &oldcwd);
+ nt_status = create_conn_struct_cwd(talloc_tos(),
+ server_event_context(),
+ server_messaging_context(),
+ &conn,
+ printdollar_snum,
+ lp_path(talloc_tos(), printdollar_snum),
+ session_info, &oldcwd);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0,("delete_driver_files: create_conn_struct "
"returned %s\n", nt_errstr(nt_status)));
return false;
}
+ nt_status = set_conn_force_user_group(conn, printdollar_snum);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(0, ("failed set force user / group\n"));
+ ret = false;
+ goto err_free_conn;
+ }
+
+ if (!become_user_by_session(conn, session_info)) {
+ DEBUG(0, ("failed to become user\n"));
+ ret = false;
+ goto err_free_conn;
+ }
+
if ( !CAN_WRITE(conn) ) {
DEBUG(3,("delete_driver_files: Cannot delete print driver when [print$] is read-only\n"));
- goto fail;
+ ret = false;
+ goto err_out;
+ }
+
+ short_arch = get_short_archi(r->architecture);
+ if (short_arch == NULL) {
+ DEBUG(0, ("bad architecture %s\n", r->architecture));
+ ret = false;
+ goto err_out;
}
- /* now delete the files; must strip the '\print$' string from
- fron of path */
+ /* now delete the files */
if (r->driver_path && r->driver_path[0]) {
- if ((s = strchr(&r->driver_path[1], '\\')) != NULL) {
- file = s;
- DEBUG(10,("deleting driverfile [%s]\n", s));
- driver_unlink_internals(conn, file);
- }
+ DEBUG(10,("deleting driverfile [%s]\n", r->driver_path));
+ driver_unlink_internals(conn, short_arch, r->version, r->driver_path);
}
if (r->config_file && r->config_file[0]) {
- if ((s = strchr(&r->config_file[1], '\\')) != NULL) {
- file = s;
- DEBUG(10,("deleting configfile [%s]\n", s));
- driver_unlink_internals(conn, file);
- }
+ DEBUG(10,("deleting configfile [%s]\n", r->config_file));
+ driver_unlink_internals(conn, short_arch, r->version, r->config_file);
}
if (r->data_file && r->data_file[0]) {
- if ((s = strchr(&r->data_file[1], '\\')) != NULL) {
- file = s;
- DEBUG(10,("deleting datafile [%s]\n", s));
- driver_unlink_internals(conn, file);
- }
+ DEBUG(10,("deleting datafile [%s]\n", r->data_file));
+ driver_unlink_internals(conn, short_arch, r->version, r->data_file);
}
if (r->help_file && r->help_file[0]) {
- if ((s = strchr(&r->help_file[1], '\\')) != NULL) {
- file = s;
- DEBUG(10,("deleting helpfile [%s]\n", s));
- driver_unlink_internals(conn, file);
- }
+ DEBUG(10,("deleting helpfile [%s]\n", r->help_file));
+ driver_unlink_internals(conn, short_arch, r->version, r->help_file);
}
- /* check if we are done removing files */
-
if (r->dependent_files) {
+ int i = 0;
while (r->dependent_files[i] && r->dependent_files[i][0]) {
- char *p;
-
- /* bypass the "\print$" portion of the path */
-
- if ((p = strchr(r->dependent_files[i]+1, '\\')) != NULL) {
- file = p;
- DEBUG(10,("deleting dependent file [%s]\n", file));
- driver_unlink_internals(conn, file);
- }
-
+ DEBUG(10,("deleting dependent file [%s]\n", r->dependent_files[i]));
+ driver_unlink_internals(conn, short_arch, r->version, r->dependent_files[i]);
i++;
}
}
- goto done;
- fail:
- ret = false;
- done:
+ ret = true;
+ err_out:
+ unbecome_user();
+ err_free_conn:
if (conn != NULL) {
vfs_ChDir(conn, oldcwd);
+ SMB_VFS_DISCONNECT(conn);
conn_free(conn);
}
return ret;
2: file doesn't exist
3: can't allocate memory
4: can't free memory
- 5: non existant struct
+ 5: non existent struct
*/
/*
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)
+WERROR print_access_check(const struct auth_session_info *session_info,
+ struct messaging_context *msg_ctx, int snum,
+ int access_type)
{
struct spoolss_security_descriptor *secdesc = NULL;
uint32 access_granted;
WERROR result;
const char *pname;
TALLOC_CTX *mem_ctx = NULL;
- SE_PRIV se_printop = SE_PRINT_OPERATOR;
/* If user is NULL then use the current_user structure */
/* Always allow root or SE_PRINT_OPERATROR to do anything */
- if (server_info->utok.uid == sec_initial_uid()
- || user_has_privileges(server_info->ptok, &se_printop ) ) {
- return True;
+ if ((session_info->unix_token->uid == sec_initial_uid())
+ || security_token_has_privilege(session_info->security_token,
+ SEC_PRIV_PRINT_OPERATOR)) {
+ return WERR_OK;
}
/* Get printer name */
- pname = lp_printername(snum);
+ pname = lp_printername(talloc_tos(), snum);
if (!pname || !*pname) {
- errno = EACCES;
- return False;
+ return WERR_ACCESS_DENIED;
}
/* Get printer security descriptor */
if(!(mem_ctx = talloc_init("print_access_check"))) {
- errno = ENOMEM;
- return False;
+ return WERR_NOMEM;
}
- result = winreg_get_printer_secdesc(mem_ctx,
- server_info,
+ result = winreg_get_printer_secdesc_internal(mem_ctx,
+ get_session_info_system(),
+ msg_ctx,
pname,
&secdesc);
if (!W_ERROR_IS_OK(result)) {
talloc_destroy(mem_ctx);
- errno = ENOMEM;
- return False;
+ return WERR_NOMEM;
}
if (access_type == JOB_ACCESS_ADMINISTER) {
false);
if (!NT_STATUS_IS_OK(status)) {
talloc_destroy(mem_ctx);
- errno = map_errno_from_nt_status(status);
- return False;
+ return ntstatus_to_werror(status);
}
map_job_permissions(secdesc);
}
/* Check access */
- status = se_access_check(secdesc, server_info->ptok, access_type,
+ status = se_access_check(secdesc, session_info->security_token, access_type,
&access_granted);
DEBUG(4, ("access check was %s\n", NT_STATUS_IS_OK(status) ? "SUCCESS" : "FAILURE"));
- /* see if we need to try the printer admin list */
-
- if (!NT_STATUS_IS_OK(status) &&
- (token_contains_name_in_list(uidtoname(server_info->utok.uid),
- server_info->info3->base.domain.string,
- NULL, server_info->ptok,
- lp_printer_admin(snum)))) {
- talloc_destroy(mem_ctx);
- return True;
- }
-
talloc_destroy(mem_ctx);
- if (!NT_STATUS_IS_OK(status)) {
- errno = EACCES;
- }
-
- return NT_STATUS_IS_OK(status);
+ return ntstatus_to_werror(status);
}
/****************************************************************************
Check the time parameters allow a print operation.
*****************************************************************************/
-bool print_time_access_check(struct auth_serversupplied_info *server_info,
+bool print_time_access_check(const struct auth_session_info *session_info,
+ struct messaging_context *msg_ctx,
const char *servicename)
{
struct spoolss_PrinterInfo2 *pinfo2 = NULL;
struct tm *t;
uint32 mins;
- result = winreg_get_printer(NULL, server_info,
- NULL, servicename, &pinfo2);
+ result = winreg_get_printer_internal(NULL, session_info, msg_ctx,
+ servicename, &pinfo2);
if (!W_ERROR_IS_OK(result)) {
return False;
}
}
void nt_printer_remove(TALLOC_CTX *mem_ctx,
- struct auth_serversupplied_info *server_info,
+ const struct auth_session_info *session_info,
+ struct messaging_context *msg_ctx,
const char *printer)
{
WERROR result;
- result = winreg_delete_printer_key(mem_ctx, server_info, printer, "");
+ result = winreg_delete_printer_key_internal(mem_ctx, session_info, msg_ctx,
+ printer, "");
+ if (!W_ERROR_IS_OK(result)) {
+ DEBUG(0, ("nt_printer_remove: failed to remove printer %s: "
+ "%s\n", printer, win_errstr(result)));
+ }
+}
+
+void nt_printer_add(TALLOC_CTX *mem_ctx,
+ const struct auth_session_info *session_info,
+ struct messaging_context *msg_ctx,
+ const char *printer)
+{
+ WERROR result;
+
+ result = winreg_create_printer_internal(mem_ctx, session_info, msg_ctx,
+ printer);
if (!W_ERROR_IS_OK(result)) {
- DEBUG(0, ("nt_printer_remove: failed to remove rpinter %s",
- printer));
+ DEBUG(0, ("nt_printer_add: failed to add printer %s: %s\n",
+ printer, win_errstr(result)));
}
}