*/
#include "includes.h"
-#include "librpc/gen_ndr/messaging.h"
-#include "printing/pcap.h"
#include "printing/nt_printing_tdb.h"
-#include "printing/nt_printing_migrate.h"
-#include "registry.h"
-#include "registry/reg_objects.h"
-#include "../librpc/gen_ndr/ndr_security.h"
#include "../librpc/gen_ndr/ndr_spoolss.h"
-#include "rpc_server/srv_spoolss_util.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 "auth.h"
+#include "messages.h"
+#include "rpc_server/spoolss/srv_spoolss_nt.h"
/* Map generic permissions to printer object specific permissions */
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));
/****************************************************************************
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_serversupplied_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);
+ 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 (!NT_STATUS_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_serversupplied_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_serversupplied_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_serversupplied_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);
+ 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);
+ return err;
}
/****************************************************************************
****************************************************************************/
bool printer_driver_in_use(TALLOC_CTX *mem_ctx,
- struct auth_serversupplied_info *server_info,
+ const struct auth_serversupplied_info *session_info,
+ struct messaging_context *msg_ctx,
const struct spoolss_DriverInfo8 *r)
{
int snum;
continue;
}
- result = winreg_get_printer(mem_ctx, server_info, NULL,
- lp_servicename(snum), &pinfo2);
+ result = winreg_get_printer(mem_ctx, session_info, msg_ctx,
+ lp_servicename(snum),
+ &pinfo2);
if (!W_ERROR_IS_OK(result)) {
continue; /* skip */
}
"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, session_info, msg_ctx,
"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, session_info, msg_ctx,
"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, session_info, msg_ctx,
"Windows NT x86",
r->driver_name,
2, &driver);
****************************************************************************/
bool printer_driver_files_in_use(TALLOC_CTX *mem_ctx,
- struct auth_serversupplied_info *server_info,
+ const struct auth_serversupplied_info *session_info,
+ struct messaging_context *msg_ctx,
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, session_info, msg_ctx,
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, session_info, msg_ctx,
info->architecture, drivers[i],
version, &driver);
if (!W_ERROR_IS_OK(result)) {
this.
****************************************************************************/
-bool delete_driver_files(struct auth_serversupplied_info *server_info,
+bool delete_driver_files(const struct auth_serversupplied_info *session_info,
const struct spoolss_DriverInfo8 *r)
{
int i = 0;
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);
+ 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;
}
/* now delete the files; must strip the '\print$' string from
}
}
- 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;
3) "printer admins" (may result in numerous calls to winbind)
****************************************************************************/
-bool print_access_check(struct auth_serversupplied_info *server_info, int snum,
+bool print_access_check(const struct auth_serversupplied_info *session_info,
+ struct messaging_context *msg_ctx, int snum,
int access_type)
{
struct spoolss_security_descriptor *secdesc = NULL;
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 ) ) {
+ if (session_info->utok.uid == sec_initial_uid()
+ || security_token_has_privilege(session_info->security_token, SEC_PRIV_PRINT_OPERATOR)) {
return True;
}
}
result = winreg_get_printer_secdesc(mem_ctx,
- server_info,
+ get_session_info_system(),
+ msg_ctx,
pname,
&secdesc);
if (!W_ERROR_IS_OK(result)) {
}
/* 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,
+ (token_contains_name_in_list(uidtoname(session_info->utok.uid),
+ session_info->info3->base.domain.string,
+ NULL, session_info->security_token,
lp_printer_admin(snum)))) {
talloc_destroy(mem_ctx);
return True;
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_serversupplied_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(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_serversupplied_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(mem_ctx, session_info, msg_ctx,
+ printer, "");
if (!W_ERROR_IS_OK(result)) {
DEBUG(0, ("nt_printer_remove: failed to remove rpinter %s",
printer));