#include "includes.h"
-extern struct current_user current_user;
-
static TDB_CONTEXT *tdb_forms; /* used for forms files */
static TDB_CONTEXT *tdb_drivers; /* used for driver files */
static TDB_CONTEXT *tdb_printers; /* used for printers files */
SERVER_ALL_ACCESS
};
+/* Map generic permissions to job object specific permissions */
+
+const struct generic_mapping job_generic_mapping = {
+ JOB_READ,
+ JOB_WRITE,
+ JOB_EXECUTE,
+ JOB_ALL_ACCESS
+};
+
/* We need one default form to support our default printer. Msoft adds the
forms it wants and in the ORDER it wants them (note: DEVMODE papersize is an
array index). Letter is always first, so (for the current code) additions
DEBUG(0,("upgrade_to_version_3: upgrading print tdb's to version 3\n"));
for (kbuf = tdb_firstkey(tdb_drivers); kbuf.dptr;
- newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
+ newkey = tdb_nextkey(tdb_drivers, kbuf), free(kbuf.dptr), kbuf=newkey) {
dbuf = tdb_fetch(tdb_drivers, kbuf);
int result, i;
uint32 sd_size;
size_t size_new_sec;
- DOM_SID sid;
if (!data.dptr || data.dsize == 0) {
return 0;
ZERO_STRUCT( ps );
- prs_init( &ps, 0, ctx, UNMARSHALL );
+ prs_init_empty( &ps, ctx, UNMARSHALL );
prs_give_memory( &ps, (char *)data.dptr, data.dsize, False );
if ( !sec_io_desc_buf( "sec_desc_upg_fn", &sd_orig, &ps, 1 ) ) {
/* create a new SEC_DESC with the appropriate owner and group SIDs */
- string_to_sid(&sid, "S-1-5-32-544" );
new_sec = make_sec_desc( ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
- &sid, &sid,
- NULL, NULL, &size_new_sec );
+ &global_sid_Builtin_Administrators,
+ &global_sid_Builtin_Administrators,
+ NULL, NULL, &size_new_sec );
if (!new_sec) {
prs_mem_free( &ps );
return 0;
sd_size = ndr_size_security_descriptor(sd_store->sd, 0)
+ sizeof(SEC_DESC_BUF);
- prs_init(&ps, sd_size, ctx, MARSHALL);
+ if ( !prs_init(&ps, sd_size, ctx, MARSHALL) ) {
+ DEBUG(0,("sec_desc_upg_fn: Failed to allocate prs memory for %s\n", key.dptr ));
+ return 0;
+ }
if ( !sec_io_desc_buf( "sec_desc_upg_fn", &sd_store, &ps, 1 ) ) {
DEBUG(0,("sec_desc_upg_fn: Failed to parse new sec_desc for %s\n", key.dptr ));
if ( lp_security() == SEC_ADS ) {
win_rc = check_published_printers();
if (!W_ERROR_IS_OK(win_rc))
- DEBUG(0, ("nt_printing_init: error checking published printers: %s\n", dos_errstr(win_rc)));
+ DEBUG(0, ("nt_printing_init: error checking published printers: %s\n", win_errstr(win_rc)));
}
return True;
for (kbuf = tdb_firstkey(tdb_forms);
kbuf.dptr;
- newkey = tdb_nextkey(tdb_forms, kbuf), safe_free(kbuf.dptr), kbuf=newkey)
+ newkey = tdb_nextkey(tdb_forms, kbuf), free(kbuf.dptr), kbuf=newkey)
{
if (strncmp((const char *)kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0)
continue;
for (kbuf = tdb_firstkey(tdb_drivers);
kbuf.dptr;
- newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
+ newkey = tdb_nextkey(tdb_drivers, kbuf), free(kbuf.dptr), kbuf=newkey) {
if (strncmp((const char *)kbuf.dptr, key, strlen(key)) != 0)
continue;
goto error_exit;
}
- status = open_file_ntcreate(conn, NULL, filepath, &stat_buf,
- FILE_GENERIC_READ,
- FILE_SHARE_READ|FILE_SHARE_WRITE,
- FILE_OPEN,
- 0,
- FILE_ATTRIBUTE_NORMAL,
- INTERNAL_OPEN_ONLY,
- NULL, &fsp);
+ status = SMB_VFS_CREATE_FILE(
+ conn, /* conn */
+ NULL, /* req */
+ 0, /* root_dir_fid */
+ filepath, /* fname */
+ 0, /* create_file_flags */
+ 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, /* allocation_size */
+ NULL, /* sd */
+ NULL, /* ea_list */
+ &fsp, /* result */
+ NULL, /* pinfo */
+ &stat_buf); /* psbuf */
if (!NT_STATUS_IS_OK(status)) {
/* Old file not found, so by definition new file is in fact newer */
DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", old_create_time));
}
}
- close_file(fsp, NORMAL_CLOSE);
+ close_file(NULL, fsp, NORMAL_CLOSE);
+ fsp = NULL;
/* Get file version info (if available) for new file */
filepath = driver_unix_convert(conn,new_file,&stat_buf);
goto error_exit;
}
- status = open_file_ntcreate(conn, NULL, filepath, &stat_buf,
- FILE_GENERIC_READ,
- FILE_SHARE_READ|FILE_SHARE_WRITE,
- FILE_OPEN,
- 0,
- FILE_ATTRIBUTE_NORMAL,
- INTERNAL_OPEN_ONLY,
- NULL, &fsp);
+ status = SMB_VFS_CREATE_FILE(
+ conn, /* conn */
+ NULL, /* req */
+ 0, /* root_dir_fid */
+ filepath, /* fname */
+ 0, /* create_file_flags */
+ 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, /* allocation_size */
+ NULL, /* sd */
+ NULL, /* ea_list */
+ &fsp, /* result */
+ NULL, /* pinfo */
+ &stat_buf); /* psbuf */
if (!NT_STATUS_IS_OK(status)) {
/* New file not found, this shouldn't occur if the caller did its job */
DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", new_create_time));
}
}
- close_file(fsp, NORMAL_CLOSE);
+ close_file(NULL, fsp, NORMAL_CLOSE);
+ fsp = NULL;
if (use_version && (new_major != old_major || new_minor != old_minor)) {
/* Compare versions and choose the larger version number */
error_exit:
if(fsp)
- close_file(fsp, NORMAL_CLOSE);
+ close_file(NULL, fsp, NORMAL_CLOSE);
return -1;
}
/****************************************************************************
Determine the correct cVersion associated with an architecture and driver
****************************************************************************/
-static uint32 get_correct_cversion(const char *architecture, fstring driverpath_in,
- struct current_user *user, WERROR *perr)
+static uint32 get_correct_cversion(struct pipes_struct *p,
+ const char *architecture,
+ fstring driverpath_in,
+ WERROR *perr)
{
int cversion;
NTSTATUS nt_status;
char *driverpath = NULL;
- DATA_BLOB null_pw;
- fstring res_type;
files_struct *fsp = NULL;
SMB_STRUCT_STAT st;
- connection_struct *conn;
+ connection_struct *conn = NULL;
NTSTATUS status;
+ char *oldcwd;
+ fstring printdollar;
+ int printdollar_snum;
SET_STAT_INVALID(st);
return 3;
}
- /*
- * Connect to the print$ share under the same account as the user connected
- * to the rpc pipe. Note we must still be root to do this.
- */
+ fstrcpy(printdollar, "print$");
- /* Null password is ok - we are already an authenticated user... */
- null_pw = data_blob_null;
- fstrcpy(res_type, "A:");
- become_root();
- conn = make_connection_with_chdir("print$", null_pw, res_type, user->vuid, &nt_status);
- unbecome_root();
-
- if (conn == NULL) {
- DEBUG(0,("get_correct_cversion: Unable to connect\n"));
- *perr = ntstatus_to_werror(nt_status);
+ printdollar_snum = find_service(printdollar);
+ if (printdollar_snum == -1) {
+ *perr = WERR_NO_SUCH_SHARE;
return -1;
}
- /* We are temporarily becoming the connection user. */
- if (!become_user(conn, user->vuid)) {
- DEBUG(0,("get_correct_cversion: Can't become user!\n"));
- *perr = WERR_ACCESS_DENIED;
+ nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum,
+ lp_pathname(printdollar_snum),
+ p->server_info, &oldcwd);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(0,("get_correct_cversion: create_conn_struct "
+ "returned %s\n", nt_errstr(nt_status)));
+ *perr = ntstatus_to_werror(nt_status);
return -1;
}
goto error_exit;
}
- status = open_file_ntcreate(conn, NULL, driverpath, &st,
- FILE_GENERIC_READ,
- FILE_SHARE_READ|FILE_SHARE_WRITE,
- FILE_OPEN,
- 0,
- FILE_ATTRIBUTE_NORMAL,
- INTERNAL_OPEN_ONLY,
- NULL, &fsp);
+ status = SMB_VFS_CREATE_FILE(
+ conn, /* conn */
+ NULL, /* req */
+ 0, /* root_dir_fid */
+ driverpath, /* fname */
+ 0, /* create_file_flags */
+ 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, /* allocation_size */
+ NULL, /* sd */
+ NULL, /* ea_list */
+ &fsp, /* result */
+ NULL, /* pinfo */
+ &st); /* psbuf */
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
driverpath, cversion));
- close_file(fsp, NORMAL_CLOSE);
- close_cnum(conn, user->vuid);
- unbecome_user();
- *perr = WERR_OK;
- return cversion;
-
-
- error_exit:
-
- if(fsp)
- close_file(fsp, NORMAL_CLOSE);
+ goto done;
- close_cnum(conn, user->vuid);
- unbecome_user();
- return -1;
+ error_exit:
+ cversion = -1;
+ done:
+ if (fsp != NULL) {
+ close_file(NULL, fsp, NORMAL_CLOSE);
+ }
+ if (conn != NULL) {
+ vfs_ChDir(conn, oldcwd);
+ conn_free_internal(conn);
+ }
+ if (cversion != -1) {
+ *perr = WERR_OK;
+ }
+ return cversion;
}
/****************************************************************************
****************************************************************************/
-static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver,
- struct current_user *user)
+static WERROR clean_up_driver_struct_level_3(struct pipes_struct *rpc_pipe,
+ NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
{
const char *architecture;
fstring new_name;
* NT 4: cversion=2
* NT2K: cversion=3
*/
- if ((driver->cversion = get_correct_cversion( architecture, driver->driverpath, user, &err)) == -1)
+ if ((driver->cversion = get_correct_cversion(rpc_pipe, architecture,
+ driver->driverpath,
+ &err)) == -1)
return err;
return WERR_OK;
/****************************************************************************
****************************************************************************/
-static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver, struct current_user *user)
+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;
* NT2K: cversion=3
*/
- if ((driver->version = get_correct_cversion(architecture, driver->driverpath, user, &err)) == -1)
+ if ((driver->version = get_correct_cversion(rpc_pipe, architecture,
+ driver->driverpath,
+ &err)) == -1)
return err;
return WERR_OK;
/****************************************************************************
****************************************************************************/
-WERROR clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
- uint32 level, struct current_user *user)
+WERROR clean_up_driver_struct(struct pipes_struct *rpc_pipe,
+ NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
+ uint32 level)
{
switch (level) {
case 3:
{
NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
driver=driver_abstract.info_3;
- return clean_up_driver_struct_level_3(driver, user);
+ 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(driver, user);
+ return clean_up_driver_struct_level_6(rpc_pipe,
+ driver);
}
default:
return WERR_INVALID_PARAM;
/****************************************************************************
****************************************************************************/
-WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level,
- struct current_user *user, WERROR *perr)
+WERROR move_driver_to_download_area(struct pipes_struct *p,
+ NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
+ uint32 level, WERROR *perr)
{
NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver;
char *new_dir = NULL;
char *old_name = NULL;
char *new_name = NULL;
- DATA_BLOB null_pw;
- connection_struct *conn;
+ connection_struct *conn = NULL;
NTSTATUS nt_status;
- fstring res_type;
SMB_STRUCT_STAT st;
int i;
TALLOC_CTX *ctx = talloc_tos();
int ver = 0;
+ char *oldcwd;
+ fstring printdollar;
+ int printdollar_snum;
*perr = WERR_OK;
return WERR_UNKNOWN_PRINTER_DRIVER;
}
- /*
- * Connect to the print$ share under the same account as the user connected to the rpc pipe.
- * Note we must be root to do this.
- */
-
- null_pw = data_blob_null;
- fstrcpy(res_type, "A:");
- become_root();
- conn = make_connection_with_chdir("print$", null_pw, res_type, user->vuid, &nt_status);
- unbecome_root();
+ fstrcpy(printdollar, "print$");
- if (conn == NULL) {
- DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
- *perr = ntstatus_to_werror(nt_status);
+ printdollar_snum = find_service(printdollar);
+ if (printdollar_snum == -1) {
+ *perr = WERR_NO_SUCH_SHARE;
return WERR_NO_SUCH_SHARE;
}
- /*
- * Save who we are - we are temporarily becoming the connection user.
- */
-
- if (!become_user(conn, conn->vuid)) {
- DEBUG(0,("move_driver_to_download_area: Can't become user!\n"));
- return WERR_ACCESS_DENIED;
+ nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum,
+ lp_pathname(printdollar_snum),
+ p->server_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;
}
- /* WE ARE NOW RUNNING AS USER conn->vuid !!!!! */
-
- /*
- * make the directories version and version\driver_name
- * under the architecture directory.
- */
DEBUG(5,("Creating first directory\n"));
new_dir = talloc_asprintf(ctx,
"%s/%d",
err_exit:
- close_cnum(conn, user->vuid);
- unbecome_user();
+ if (conn != NULL) {
+ vfs_ChDir(conn, oldcwd);
+ conn_free_internal(conn);
+ }
if (W_ERROR_EQUAL(*perr, WERR_OK)) {
return WERR_OK;
regval_ctr_delvalue(ctr, val_name);
regval_ctr_addvalue(ctr, val_name, REG_MULTI_SZ,
(char *) conv_strs, str_size);
- safe_free(conv_strs);
-
+ SAFE_FREE(conv_strs);
}
/****************************************************************************
ZERO_STRUCT( unistr_guid );
- init_unistr2( &unistr_guid, smb_uuid_string(talloc_tos(), guid),
+ init_unistr2( &unistr_guid, GUID_string(talloc_tos(), &guid),
UNI_STR_TERMINATE );
regval_ctr_addvalue(ctr, "objectGUID", REG_SZ,
const char *attrs[] = {"objectGUID", NULL};
struct GUID guid;
WERROR win_rc = WERR_OK;
+ size_t converted_size;
DEBUG(5, ("publishing printer %s\n", printer->info_2->printername));
return WERR_SERVER_UNAVAILABLE;
}
/* Now convert to CH_UNIX. */
- if (pull_utf8_allocate(&srv_dn, srv_dn_utf8) == (size_t)-1) {
+ if (!pull_utf8_allocate(&srv_dn, srv_dn_utf8, &converted_size)) {
ldap_memfree(srv_dn_utf8);
ldap_memfree(srv_cn_utf8);
ads_destroy(&ads);
return WERR_SERVER_UNAVAILABLE;
}
- if (pull_utf8_allocate(&srv_cn_0, srv_cn_utf8[0]) == (size_t)-1) {
+ if (!pull_utf8_allocate(&srv_cn_0, srv_cn_utf8[0], &converted_size)) {
ldap_memfree(srv_dn_utf8);
ldap_memfree(srv_cn_utf8);
ads_destroy(&ads);
/* publish it */
ads_rc = ads_mod_printer_entry(ads, prt_dn, ctx, &mods);
- if (ads_rc.err.rc == LDAP_NO_SUCH_OBJECT)
+ 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->info_2->sharename, ads_errstr(ads_rc)));
case REG_SZ:
rpcstr_pull( guid_str, regval_data_p(guid_val),
sizeof(guid_str)-1, -1, STR_TERMINATE );
- ret = smb_string_to_uuid( guid_str, guid );
+ ret = NT_STATUS_IS_OK(GUID_from_string( guid_str, guid ));
break;
case REG_BINARY:
if ( regval_size(guid_val) != sizeof(struct GUID) ) {
memcpy( &guid, data_p, sizeof(struct GUID) );
init_unistr2( &unistr_guid,
- smb_uuid_string(talloc_tos(), guid),
+ GUID_string(talloc_tos(), &guid),
UNI_STR_TERMINATE );
regval_ctr_addvalue( printer_data->keys[key_index].values,
return;
}
- lines = file_lines_load(mapfile, &numlines,0);
+ 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));
- SAFE_FREE(lines);
+ TALLOC_FREE(lines);
return;
}
DEBUG(3,("Mapped windows driver %s to os2 driver%s\n",drivername,os2_name));
set_last_from_to(drivername,os2_name);
fstrcpy(drivername,os2_name);
- file_lines_free(lines);
+ TALLOC_FREE(lines);
return;
}
}
- file_lines_free(lines);
+ TALLOC_FREE(lines);
}
/****************************************************************************
Get a default printer info 2 struct.
****************************************************************************/
-static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 *info, const char *servername, const char* sharename)
+
+static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 *info,
+ const char *servername,
+ const char* sharename,
+ bool get_loc_com)
{
int snum = lp_servicenumber(sharename);
fstrcpy(info->datatype, "RAW");
#ifdef HAVE_CUPS
- if ( (enum printing_types)lp_printing(snum) == PRINT_CUPS ) {
+ 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) )
/****************************************************************************
****************************************************************************/
-static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info, const char *servername, const char *sharename)
+
+static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info,
+ const char *servername,
+ const char *sharename,
+ bool get_loc_com)
{
int len = 0;
int snum = lp_servicenumber(sharename);
dbuf = tdb_fetch(tdb_printers, kbuf);
if (!dbuf.dptr) {
- return get_a_printer_2_default(info, servername, sharename);
+ return get_a_printer_2_default(info, servername,
+ sharename, get_loc_com);
}
len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff",
fstrcpy(info->printername, printername);
#ifdef HAVE_CUPS
- if ( (enum printing_types)lp_printing(snum) == PRINT_CUPS ) {
+ 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) )
ZERO_STRUCT(devmode);
- prs_init(&ps, 0, ctx, UNMARSHALL);
+ prs_init_empty(&ps, ctx, UNMARSHALL);
ps.data_p = (char *)data;
ps.buffer_size = data_len;
****************************************************************************/
-WERROR get_a_printer( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level,
- const char *sharename)
+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;
sizeof(servername)-1 );
}
- result = get_a_printer_2( (*pp_printer)->info_2, servername, sharename );
-
-
+ 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 */
-
+
if ( !W_ERROR_IS_OK(result) ) {
TALLOC_FREE( *pp_printer );
DEBUG(10,("get_a_printer: [%s] level %u returning %s\n",
- sharename, (unsigned int)level, dos_errstr(result)));
+ sharename, (unsigned int)level, win_errstr(result)));
return result;
}
return WERR_OK;
}
+WERROR get_a_printer( Printer_entry *print_hnd,
+ NT_PRINTER_INFO_LEVEL **pp_printer,
+ uint32 level,
+ const char *sharename)
+{
+ return get_a_printer_internal(print_hnd, pp_printer, level,
+ sharename, true);
+}
+
+WERROR get_a_printer_search( Printer_entry *print_hnd,
+ NT_PRINTER_INFO_LEVEL **pp_printer,
+ uint32 level,
+ const char *sharename)
+{
+ return get_a_printer_internal(print_hnd, pp_printer, level,
+ sharename, false);
+}
+
/****************************************************************************
Deletes a NT_PRINTER_INFO_LEVEL struct.
****************************************************************************/
static bool drv_file_in_use( char* file, NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
{
int i = 0;
-
+
if ( !info )
return False;
-
+
+ /* mz: skip files that are in the list but already deleted */
+ if (!file || !file[0]) {
+ return false;
+ }
+
if ( strequal(file, info->driverpath) )
return True;
Upon return, *info has been modified to only contain the driver files
which are not in use
+
+ Fix from mz:
+
+ This needs to check all drivers to ensure that all files in use
+ have been removed from *info, not just the ones in the first
+ match.
****************************************************************************/
bool printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
uint32 version;
fstring *list = NULL;
NT_PRINTER_DRIVER_INFO_LEVEL driver;
-
+ bool in_use = false;
+
if ( !info )
return False;
if ( !strequal(info->name, driver.info_3->name) ) {
if ( trim_overlap_drv_files(info, driver.info_3) ) {
- free_a_printer_driver(driver, 3);
- SAFE_FREE( list );
- return True;
+ /* mz: Do not instantly return -
+ * we need to ensure this file isn't
+ * also in use by other drivers. */
+ in_use = true;
}
}
if ( DEBUGLEVEL >= 20 )
dump_a_printer_driver( driver, 3 );
- return False;
+ return in_use;
}
/****************************************************************************
this.
****************************************************************************/
-static bool delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct current_user *user )
+static bool delete_driver_files(struct pipes_struct *rpc_pipe,
+ NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3)
{
int i = 0;
char *s;
const char *file;
connection_struct *conn;
- DATA_BLOB null_pw;
NTSTATUS nt_status;
- fstring res_type;
SMB_STRUCT_STAT st;
+ char *oldcwd;
+ fstring printdollar;
+ int printdollar_snum;
+ bool ret = false;
if ( !info_3 )
return False;
DEBUG(6,("delete_driver_files: deleting driver [%s] - version [%d]\n", info_3->name, info_3->cversion));
- /*
- * Connect to the print$ share under the same account as the
- * user connected to the rpc pipe. Note we must be root to
- * do this.
- */
+ fstrcpy(printdollar, "print$");
- null_pw = data_blob_null;
- fstrcpy(res_type, "A:");
- become_root();
- conn = make_connection_with_chdir( "print$", null_pw, res_type, user->vuid, &nt_status );
- unbecome_root();
+ printdollar_snum = find_service(printdollar);
+ if (printdollar_snum == -1) {
+ return false;
+ }
- if ( !conn ) {
- DEBUG(0,("delete_driver_files: Unable to connect\n"));
- return False;
+ nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum,
+ lp_pathname(printdollar_snum),
+ rpc_pipe->server_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;
}
if ( !CAN_WRITE(conn) ) {
DEBUG(3,("delete_driver_files: Cannot delete print driver when [print$] is read-only\n"));
- return False;
- }
-
- /* Save who we are - we are temporarily becoming the connection user. */
-
- if ( !become_user(conn, conn->vuid) ) {
- DEBUG(0,("delete_driver_files: Can't become user!\n"));
- return False;
+ goto fail;
}
/* now delete the files; must strip the '\print$' string from
}
}
- unbecome_user();
-
- return true;
+ goto done;
+ fail:
+ ret = false;
+ done:
+ if (conn != NULL) {
+ vfs_ChDir(conn, oldcwd);
+ conn_free_internal(conn);
+ }
+ return ret;
}
/****************************************************************************
previously looked up.
***************************************************************************/
-WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct current_user *user,
- uint32 version, bool delete_files )
+WERROR delete_printer_driver(struct pipes_struct *rpc_pipe,
+ NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3,
+ uint32 version, bool delete_files )
{
char *key = NULL;
const char *arch;
*/
if ( delete_files )
- delete_driver_files( info_3, user );
+ delete_driver_files(rpc_pipe, info_3);
DEBUG(5,("delete_printer_driver: driver delete successful [%s]\n", key));
SAFE_FREE(key);
/* Store the security descriptor in a tdb */
- prs_init(&ps,
- (uint32)ndr_size_security_descriptor(new_secdesc_ctr->sd, 0)
- + sizeof(SEC_DESC_BUF), mem_ctx, MARSHALL);
+ if (!prs_init(&ps,
+ (uint32)ndr_size_security_descriptor(new_secdesc_ctr->sd, 0)
+ + sizeof(SEC_DESC_BUF), mem_ctx, MARSHALL) ) {
+ status = WERR_NOMEM;
+ goto out;
+ }
+
prs_init_done = true;
{
SEC_ACE ace[5]; /* max number of ace entries */
int i = 0;
- SEC_ACCESS sa;
+ uint32_t sa;
SEC_ACL *psa = NULL;
SEC_DESC_BUF *sdb = NULL;
SEC_DESC *psd = NULL;
/* Create an ACE where Everyone is allowed to print */
- init_sec_access(&sa, PRINTER_ACE_PRINT);
+ sa = PRINTER_ACE_PRINT;
init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
sid_copy(&domadmins_sid, get_global_sam_sid());
sid_append_rid(&domadmins_sid, DOMAIN_GROUP_RID_ADMINS);
- init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
+ 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);
else if (secrets_fetch_domain_sid(lp_workgroup(), &adm_sid)) {
sid_append_rid(&adm_sid, DOMAIN_USER_RID_ADMIN);
- init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
+ 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);
/* add BUILTIN\Administrators as FULL CONTROL */
- init_sec_access(&sa, PRINTER_ACE_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);
/* Save default security descriptor for later */
- prs_init(&ps, (uint32)ndr_size_security_descriptor((*secdesc_ctr)->sd, 0) +
- sizeof(SEC_DESC_BUF), ctx, MARSHALL);
+ if (!prs_init(&ps, (uint32)ndr_size_security_descriptor((*secdesc_ctr)->sd, 0) +
+ sizeof(SEC_DESC_BUF), ctx, MARSHALL))
+ return False;
if (sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
tdb_prs_store(tdb_printers, kbuf, &ps);
}
}
+void map_job_permissions(SEC_DESC *sd)
+{
+ int i;
+
+ for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
+ se_map_generic(&sd->dacl->aces[i].access_mask,
+ &job_generic_mapping);
+ }
+}
+
+
/****************************************************************************
Check a user has permissions to perform the given operation. We use the
permission constants defined in include/rpc_spoolss.h to check the various
3) "printer admins" (may result in numerous calls to winbind)
****************************************************************************/
-bool print_access_check(struct current_user *user, int snum, int access_type)
+bool print_access_check(struct auth_serversupplied_info *server_info, int snum,
+ int access_type)
{
SEC_DESC_BUF *secdesc = NULL;
uint32 access_granted;
NTSTATUS status;
- bool 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 */
- if (!user)
- user = ¤t_user;
-
/* Always allow root or SE_PRINT_OPERATROR to do anything */
- if ( user->ut.uid == 0 || user_has_privileges(user->nt_user_token, &se_printop ) ) {
+ if (server_info->utok.uid == 0
+ || user_has_privileges(server_info->ptok, &se_printop ) ) {
return True;
}
against. This is because print jobs are child objects
objects of a printer. */
- secdesc = se_create_child_secdesc(mem_ctx, parent_secdesc->sd, False);
+ status = se_create_child_secdesc_buf(mem_ctx, &secdesc, parent_secdesc->sd, False);
- if (!secdesc) {
+ if (!NT_STATUS_IS_OK(status)) {
talloc_destroy(mem_ctx);
- errno = ENOMEM;
+ errno = map_errno_from_nt_status(status);
return False;
}
- /* Now this is the bit that really confuses me. The access
- type needs to be changed from JOB_ACCESS_ADMINISTER to
- PRINTER_ACCESS_ADMINISTER for this to work. Something
- to do with the child (job) object becoming like a
- printer?? -tpot */
-
- access_type = PRINTER_ACCESS_ADMINISTER;
+ map_job_permissions(secdesc->sd);
+ } else {
+ map_printer_permissions(secdesc->sd);
}
-
- /* Check access */
-
- map_printer_permissions(secdesc->sd);
- result = se_access_check(secdesc->sd, user->nt_user_token, access_type,
- &access_granted, &status);
+ /* Check access */
+ status = se_access_check(secdesc->sd, server_info->ptok, access_type,
+ &access_granted);
- DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE"));
+ 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 ((access_granted == 0) &&
- (token_contains_name_in_list(uidtoname(user->ut.uid), NULL,
- user->nt_user_token,
+ (token_contains_name_in_list(uidtoname(server_info->utok.uid),
+ NULL, NULL, server_info->ptok,
lp_printer_admin(snum)))) {
talloc_destroy(mem_ctx);
return True;
talloc_destroy(mem_ctx);
- if (!result) {
+ if (!NT_STATUS_IS_OK(status)) {
errno = EACCES;
}
- return result;
+ return NT_STATUS_IS_OK(status);
}
/****************************************************************************