* Unix SMB/CIFS implementation.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-2000,
- * Copyright (C) Jean François Micouleau 1998-2000.
+ * Copyright (C) Jean François Micouleau 1998-2000.
* Copyright (C) Gerald Carter 2002-2003.
*
* This program is free software; you can redistribute it and/or modify
#define SPL_ARCH_W32MIPS "W32MIPS"
#define SPL_ARCH_W32ALPHA "W32ALPHA"
#define SPL_ARCH_W32PPC "W32PPC"
+#define SPL_ARCH_IA64 "IA64"
+#define SPL_ARCH_X64 "x64"
static const struct table_node archi_table[]= {
{"Windows NT R4000", SPL_ARCH_W32MIPS, 2 },
{"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA, 2 },
{"Windows NT PowerPC", SPL_ARCH_W32PPC, 2 },
+ {"Windows IA64", SPL_ARCH_IA64, 3 },
+ {"Windows x64", SPL_ARCH_X64, 3 },
{NULL, "", -1 }
};
{
static pid_t local_pid;
const char *vstring = "INFO/version";
+ WERROR win_rc;
if (tdb_drivers && tdb_printers && tdb_forms && local_pid == sys_getpid())
return True;
message_register( MSG_PRINTERDATA_INIT_RESET, reset_all_printerdata );
+ /*
+ * register callback to handle invalidating the printer cache
+ * between smbd processes.
+ */
+
+ message_register( MSG_PRINTER_MOD, receive_printer_mod_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 claim_connection() */
+
+
+ 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)));
+ }
return True;
}
+/*******************************************************************
+ Function to allow filename parsing "the old way".
+********************************************************************/
+
+static BOOL driver_unix_convert(char *name,connection_struct *conn,
+ char *saved_last_component, BOOL *bad_path, SMB_STRUCT_STAT *pst)
+{
+ unix_format(name);
+ unix_clean_name(name);
+ trim_string(name,"/","/");
+ return unix_convert(name, conn, saved_last_component, bad_path, pst);
+}
+
/*******************************************************************
tdb traversal function for counting printers.
********************************************************************/
if (ret != dbuf.dsize)
continue;
- tl = Realloc(*list, sizeof(nt_forms_struct)*(n+1));
+ tl = SMB_REALLOC_ARRAY(*list, nt_forms_struct, n+1);
if (!tl) {
DEBUG(0,("get_ntforms: Realloc fail.\n"));
return 0;
unistr2_to_ascii(form_name, &form->name, sizeof(form_name)-1);
for (n=0; n<*count; n++) {
- if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
- DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
+ if ( strequal((*list)[n].name, form_name) ) {
update=True;
break;
}
}
if (update==False) {
- if((tl=Realloc(*list, (n+1)*sizeof(nt_forms_struct))) == NULL) {
+ if((tl=SMB_REALLOC_ARRAY(*list, nt_forms_struct, n+1)) == NULL) {
DEBUG(0,("add_a_form: failed to enlarge forms list!\n"));
return False;
}
(*list)[n].right=form->right;
(*list)[n].bottom=form->bottom;
+ DEBUG(6,("add_a_form: Successfully %s form [%s]\n",
+ update ? "updated" : "added", form_name));
+
return True;
}
if (strncmp(kbuf.dptr, key, strlen(key)) != 0)
continue;
- if((fl = Realloc(*list, sizeof(fstring)*(total+1))) == NULL) {
+ if((fl = SMB_REALLOC_ARRAY(*list, fstring, total+1)) == NULL) {
DEBUG(0,("get_ntdrivers: failed to enlarge list!\n"));
return -1;
}
static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 *minor)
{
int i;
- char *buf;
+ char *buf = NULL;
ssize_t byte_count;
- if ((buf=malloc(PE_HEADER_SIZE)) == NULL) {
+ if ((buf=SMB_MALLOC(PE_HEADER_SIZE)) == NULL) {
DEBUG(0,("get_file_version: PE file [%s] PE Header malloc failed bytes = %d\n",
fname, PE_HEADER_SIZE));
goto error_exit;
/* Note: DOS_HEADER_SIZE < malloc'ed PE_HEADER_SIZE */
if ((byte_count = vfs_read_data(fsp, buf, DOS_HEADER_SIZE)) < DOS_HEADER_SIZE) {
- DEBUG(3,("get_file_version: File [%s] DOS header too short, bytes read = %d\n",
- fname, byte_count));
+ DEBUG(3,("get_file_version: File [%s] DOS header too short, bytes read = %lu\n",
+ fname, (unsigned long)byte_count));
goto no_version_info;
}
}
if ((byte_count = vfs_read_data(fsp, buf, PE_HEADER_SIZE)) < PE_HEADER_SIZE) {
- DEBUG(3,("get_file_version: File [%s] Windows header too short, bytes read = %d\n",
- fname, byte_count));
+ DEBUG(3,("get_file_version: File [%s] Windows header too short, bytes read = %lu\n",
+ fname, (unsigned long)byte_count));
/* Assume this isn't an error... the file just looks sort of like a PE/NE file */
goto no_version_info;
}
/* The header may be a PE (Portable Executable) or an NE (New Executable) */
if (IVAL(buf,PE_HEADER_SIGNATURE_OFFSET) == PE_HEADER_SIGNATURE) {
- int num_sections;
- int section_table_bytes;
+ unsigned int num_sections;
+ unsigned int section_table_bytes;
if (SVAL(buf,PE_HEADER_MACHINE_OFFSET) != PE_HEADER_MACHINE_I386) {
DEBUG(3,("get_file_version: PE file [%s] wrong machine = 0x%x\n",
/* get the section table */
num_sections = SVAL(buf,PE_HEADER_NUMBER_OF_SECTIONS);
section_table_bytes = num_sections * PE_HEADER_SECT_HEADER_SIZE;
+ if (section_table_bytes == 0)
+ goto error_exit;
+
SAFE_FREE(buf);
- if ((buf=malloc(section_table_bytes)) == NULL) {
+ if ((buf=SMB_MALLOC(section_table_bytes)) == NULL) {
DEBUG(0,("get_file_version: PE file [%s] section table malloc failed bytes = %d\n",
fname, section_table_bytes));
goto error_exit;
}
if ((byte_count = vfs_read_data(fsp, buf, section_table_bytes)) < section_table_bytes) {
- DEBUG(3,("get_file_version: PE file [%s] Section header too short, bytes read = %d\n",
- fname, byte_count));
+ DEBUG(3,("get_file_version: PE file [%s] Section header too short, bytes read = %lu\n",
+ fname, (unsigned long)byte_count));
goto error_exit;
}
int sec_offset = i * PE_HEADER_SECT_HEADER_SIZE;
if (strcmp(".rsrc", &buf[sec_offset+PE_HEADER_SECT_NAME_OFFSET]) == 0) {
- int section_pos = IVAL(buf,sec_offset+PE_HEADER_SECT_PTR_DATA_OFFSET);
- int section_bytes = IVAL(buf,sec_offset+PE_HEADER_SECT_SIZE_DATA_OFFSET);
+ unsigned int section_pos = IVAL(buf,sec_offset+PE_HEADER_SECT_PTR_DATA_OFFSET);
+ unsigned int section_bytes = IVAL(buf,sec_offset+PE_HEADER_SECT_SIZE_DATA_OFFSET);
+
+ if (section_bytes == 0)
+ goto error_exit;
SAFE_FREE(buf);
- if ((buf=malloc(section_bytes)) == NULL) {
+ if ((buf=SMB_MALLOC(section_bytes)) == NULL) {
DEBUG(0,("get_file_version: PE file [%s] version malloc failed bytes = %d\n",
fname, section_bytes));
goto error_exit;
}
if ((byte_count = vfs_read_data(fsp, buf, section_bytes)) < section_bytes) {
- DEBUG(3,("get_file_version: PE file [%s] .rsrc section too short, bytes read = %d\n",
- fname, byte_count));
+ DEBUG(3,("get_file_version: PE file [%s] .rsrc section too short, bytes read = %lu\n",
+ fname, (unsigned long)byte_count));
goto error_exit;
}
+ if (section_bytes < VS_VERSION_INFO_UNICODE_SIZE)
+ goto error_exit;
+
for (i=0; i<section_bytes-VS_VERSION_INFO_UNICODE_SIZE; i++) {
/* Scan for 1st 3 unicoded bytes followed by word aligned magic value */
if (buf[i] == 'V' && buf[i+1] == '\0' && buf[i+2] == 'S') {
/* Allocate a bit more space to speed up things */
SAFE_FREE(buf);
- if ((buf=malloc(VS_NE_BUF_SIZE)) == NULL) {
+ if ((buf=SMB_MALLOC(VS_NE_BUF_SIZE)) == NULL) {
DEBUG(0,("get_file_version: NE file [%s] malloc failed bytes = %d\n",
fname, PE_HEADER_SIZE));
goto error_exit;
/* Get file version info (if available) for previous file (if it exists) */
pstrcpy(filepath, old_file);
- unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
+ driver_unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
fsp = open_file_shared(conn, filepath, &stat_buf,
- SET_OPEN_MODE(DOS_OPEN_RDONLY),
+ SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
- 0, 0, &access_mode, &action);
+ FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY, &access_mode, &action);
if (!fsp) {
/* Old file not found, so by definition new file is in fact newer */
DEBUG(10,("file_version_is_newer: Can't open old file [%s], errno = %d\n",
/* Get file version info (if available) for new file */
pstrcpy(filepath, new_file);
- unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
+ driver_unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
fsp = open_file_shared(conn, filepath, &stat_buf,
- SET_OPEN_MODE(DOS_OPEN_RDONLY),
+ SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
- 0, 0, &access_mode, &action);
+ FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY, &access_mode, &action);
if (!fsp) {
/* New file not found, this shouldn't occur if the caller did its job */
DEBUG(3,("file_version_is_newer: Can't open new file [%s], errno = %d\n",
* deriver the cversion. */
slprintf(driverpath, sizeof(driverpath)-1, "%s/%s", architecture, driverpath_in);
- unix_convert(driverpath,conn,NULL,&bad_path,&st);
+ driver_unix_convert(driverpath,conn,NULL,&bad_path,&st);
fsp = open_file_shared(conn, driverpath, &st,
- SET_OPEN_MODE(DOS_OPEN_RDONLY),
+ SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
- 0, 0, &access_mode, &action);
+ FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY, &access_mode, &action);
if (!fsp) {
DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
driverpath, errno));
pstring inbuf;
pstring outbuf;
fstring res_type;
+ BOOL bad_path;
+ SMB_STRUCT_STAT st;
int ver = 0;
int i;
*/
DEBUG(5,("Creating first directory\n"));
slprintf(new_dir, sizeof(new_dir)-1, "%s/%d", architecture, driver->cversion);
+ driver_unix_convert(new_dir, conn, NULL, &bad_path, &st);
mkdir_internal(conn, new_dir);
/* For each driver file, archi\filexxx.yyy, if there is a duplicate file
slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->driverpath);
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
NTSTATUS status;
- status = rename_internals(conn, new_name, old_name, True);
+ driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
+ status = rename_internals(conn, new_name, old_name, 0, True);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
new_name, old_name));
unlink_internals(conn, 0, new_name);
ver = -1;
}
- }
- else
+ } else {
+ driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
unlink_internals(conn, 0, new_name);
+ }
}
if (driver->datafile && strlen(driver->datafile)) {
slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->datafile);
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
NTSTATUS status;
- status = rename_internals(conn, new_name, old_name, True);
+ driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
+ status = rename_internals(conn, new_name, old_name, 0, True);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
new_name, old_name));
unlink_internals(conn, 0, new_name);
ver = -1;
}
- }
- else
+ } else {
+ driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
unlink_internals(conn, 0, new_name);
+ }
}
}
slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->configfile);
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
NTSTATUS status;
- status = rename_internals(conn, new_name, old_name, True);
+ driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
+ status = rename_internals(conn, new_name, old_name, 0, True);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
new_name, old_name));
unlink_internals(conn, 0, new_name);
ver = -1;
}
- }
- else
+ } else {
+ driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
unlink_internals(conn, 0, new_name);
+ }
}
}
slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->helpfile);
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
NTSTATUS status;
- status = rename_internals(conn, new_name, old_name, True);
+ driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
+ status = rename_internals(conn, new_name, old_name, 0, True);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
new_name, old_name));
unlink_internals(conn, 0, new_name);
ver = -1;
}
- }
- else
+ } else {
+ driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
unlink_internals(conn, 0, new_name);
+ }
}
}
slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->dependentfiles[i]);
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
NTSTATUS status;
- status = rename_internals(conn, new_name, old_name, True);
+ driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
+ status = rename_internals(conn, new_name, old_name, 0, True);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
new_name, old_name));
unlink_internals(conn, 0, new_name);
ver = -1;
}
- }
- else
+ } else {
+ driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
unlink_internals(conn, 0, new_name);
+ }
}
NextDriver: ;
}
if (len != buflen) {
char *tb;
- tb = (char *)Realloc(buf, len);
+ tb = (char *)SMB_REALLOC(buf, len);
if (!tb) {
DEBUG(0,("add_a_printer_driver_3: failed to enlarge buffer\n!"));
ret = -1;
fstrcpy(info.configfile, "");
fstrcpy(info.helpfile, "");
- if ((info.dependentfiles=(fstring *)malloc(2*sizeof(fstring))) == NULL)
+ if ((info.dependentfiles= SMB_MALLOC_ARRAY(fstring, 2)) == NULL)
return WERR_NOMEM;
memset(info.dependentfiles, '\0', 2*sizeof(fstring));
while (len < dbuf.dsize) {
fstring *tddfs;
- tddfs = (fstring *)Realloc(driver.dependentfiles,
- sizeof(fstring)*(i+2));
+ tddfs = SMB_REALLOC_ARRAY(driver.dependentfiles, fstring, i+2);
if (tddfs == NULL) {
DEBUG(0,("get_a_printer_driver_3: failed to enlarge buffer!\n"));
break;
handles are not affected.
****************************************************************************/
-uint32 del_a_printer(char *sharename)
+uint32 del_a_printer(const char *sharename)
{
pstring key;
TDB_DATA kbuf;
+ pstring printdb_path;
slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
-
kbuf.dptr=key;
kbuf.dsize=strlen(key)+1;
+ tdb_delete(tdb_printers, kbuf);
+ slprintf(key, sizeof(key)-1, "%s%s", SECDESC_PREFIX, sharename);
+ kbuf.dptr=key;
+ kbuf.dsize=strlen(key)+1;
tdb_delete(tdb_printers, kbuf);
+
+ close_all_print_db();
+
+ if (geteuid() == 0) {
+ pstrcpy(printdb_path, lock_path("printing/"));
+ pstrcat(printdb_path, sharename);
+ pstrcat(printdb_path, ".tdb");
+
+ unlink(printdb_path);
+ }
+
return 0;
}
-/* FIXME!!! Reorder so this forward declaration is not necessary --jerry */
-static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **, const char* sharename);
-static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **);
/****************************************************************************
****************************************************************************/
static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
* and printer is \\server\\printer
*
* Samba manages only local printers.
- * we currently don't support things like path=\\other_server\printer
+ * we currently don't support things like i
+ * path=\\other_server\printer
+ *
+ * We only store the printername, not \\server\printername
*/
- if (info->servername[0]!='\0') {
+ if ( info->servername[0] != '\0' ) {
trim_string(info->printername, info->servername, NULL);
trim_char(info->printername, '\\', '\0');
info->servername[0]='\0';
if (buflen != len) {
char *tb;
- tb = (char *)Realloc(buf, len);
+ tb = (char *)SMB_REALLOC(buf, len);
if (!tb) {
DEBUG(0,("update_a_printer_2: failed to enlarge buffer!\n"));
ret = WERR_NOMEM;
{
char adevice[MAXDEVICENAME];
- NT_DEVICEMODE *nt_devmode = (NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE));
+ NT_DEVICEMODE *nt_devmode = SMB_MALLOC_P(NT_DEVICEMODE);
if (nt_devmode == NULL) {
DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
ZERO_STRUCTP(nt_devmode);
- safe_strcpy(adevice, default_devicename, sizeof(adevice)-1);
+ slprintf(adevice, sizeof(adevice), "%s", default_devicename);
fstrcpy(nt_devmode->devicename, adevice);
fstrcpy(nt_devmode->formname, "Letter");
nt_devmode->mediatype = 0;
nt_devmode->dithertype = 0;
- /* non utilisés par un driver d'imprimante */
+ /* non utilisés par un driver d'imprimante */
nt_devmode->logpixels = 0;
nt_devmode->bitsperpel = 0;
nt_devmode->pelswidth = 0;
/* allocate another slot in the NT_PRINTER_KEY array */
- d = Realloc( data->keys, sizeof(NT_PRINTER_KEY)*(data->num_keys+1) );
+ d = SMB_REALLOC_ARRAY( data->keys, NT_PRINTER_KEY, data->num_keys+1);
if ( d )
data->keys = d;
/* initialze new key */
data->num_keys++;
- data->keys[key_index].name = strdup( name );
+ data->keys[key_index].name = SMB_STRDUP( name );
ZERO_STRUCTP( &data->keys[key_index].values );
/* found a match, so allocate space and copy the name */
- if ( !(ptr = Realloc( subkeys_ptr, (num_subkeys+2)*sizeof(fstring))) ) {
+ if ( !(ptr = SMB_REALLOC_ARRAY( subkeys_ptr, fstring, num_subkeys+2)) ) {
DEBUG(0,("get_printer_subkeys: Realloc failed for [%d] entries!\n",
num_subkeys+1));
SAFE_FREE( subkeys );
/* a multi-sz has to have a null string terminator, i.e., the last
string must be followed by two nulls */
- str_size = (strlen(multi_sz) + 2) * sizeof(smb_ucs2_t);
- conv_strs = calloc(str_size, 1);
+ str_size = strlen(multi_sz) + 2;
+ conv_strs = SMB_CALLOC_ARRAY(smb_ucs2_t, str_size);
+ if (!conv_strs) {
+ return;
+ }
+ /* Change to byte units. */
+ str_size *= sizeof(smb_ucs2_t);
push_ucs2(NULL, conv_strs, multi_sz, str_size,
STR_TERMINATE | STR_NOALIGN);
map_sz_into_ctr(ctr, SPOOL_REG_PRINTERNAME, info2->sharename);
map_sz_into_ctr(ctr, SPOOL_REG_SHORTSERVERNAME, global_myname());
- get_myfullname(longname);
+ get_mydnsfullname(longname);
map_sz_into_ctr(ctr, SPOOL_REG_SERVERNAME, longname);
asprintf(&allocated_string, "\\\\%s\\%s", longname, info2->sharename);
return True;
}
-static void store_printer_guid(NT_PRINTER_INFO_LEVEL_2 *info2, GUID guid)
+static void store_printer_guid(NT_PRINTER_INFO_LEVEL_2 *info2,
+ struct uuid guid)
{
int i;
REGVAL_CTR *ctr=NULL;
regval_ctr_delvalue(ctr, "objectGUID");
regval_ctr_addvalue(ctr, "objectGUID", REG_BINARY,
- (char *) &guid, sizeof(GUID));
+ (char *) &guid, sizeof(struct uuid));
}
-static WERROR publish_it(NT_PRINTER_INFO_LEVEL *printer)
+static WERROR nt_printer_publish_ads(ADS_STRUCT *ads,
+ NT_PRINTER_INFO_LEVEL *printer)
{
ADS_STATUS ads_rc;
- TALLOC_CTX *ctx = talloc_init("publish_it");
- ADS_MODLIST mods = ads_init_mods(ctx);
+ void *res;
char *prt_dn = NULL, *srv_dn, *srv_cn_0;
char *srv_dn_utf8, **srv_cn_utf8;
- void *res = NULL;
- ADS_STRUCT *ads;
+ TALLOC_CTX *ctx;
+ ADS_MODLIST mods;
const char *attrs[] = {"objectGUID", NULL};
- GUID guid;
+ struct uuid guid;
WERROR win_rc = WERR_OK;
- ZERO_STRUCT(guid);
- /* set the DsSpooler info and attributes */
- if (!(map_nt_printer_info2_to_dsspooler(printer->info_2)))
- return WERR_NOMEM;
- printer->info_2->attributes |= PRINTER_ATTRIBUTE_PUBLISHED;
- win_rc = mod_a_printer(*printer, 2);
- if (!W_ERROR_IS_OK(win_rc)) {
- DEBUG(3, ("err %d saving data\n",
- W_ERROR_V(win_rc)));
- return win_rc;
- }
-
- /* Build the ads mods */
- get_local_printer_publishing_data(ctx, &mods,
- &printer->info_2->data);
- ads_mod_str(ctx, &mods, SPOOL_REG_PRINTERNAME,
- printer->info_2->sharename);
-
- /* initial ads structure */
-
- ads = ads_init(NULL, NULL, 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)));
- ads_destroy(&ads);
- return WERR_ACCESS_DENIED;
- }
+ DEBUG(5, ("publishing printer %s\n", printer->info_2->printername));
/* figure out where to publish */
ads_find_machine_acct(ads, &res, global_myname());
return WERR_SERVER_UNAVAILABLE;
}
/* Now convert to CH_UNIX. */
- if (pull_utf8_allocate((void **) &srv_dn, srv_dn_utf8) == (size_t)-1) {
+ if (pull_utf8_allocate(&srv_dn, srv_dn_utf8) == (size_t)-1) {
ldap_memfree(srv_dn_utf8);
ldap_memfree(srv_cn_utf8);
ads_destroy(&ads);
return WERR_SERVER_UNAVAILABLE;
}
- if (pull_utf8_allocate((void **) &srv_cn_0, srv_cn_utf8[0]) == (size_t)-1) {
+ if (pull_utf8_allocate(&srv_cn_0, srv_cn_utf8[0]) == (size_t)-1) {
ldap_memfree(srv_dn_utf8);
ldap_memfree(srv_cn_utf8);
ads_destroy(&ads);
SAFE_FREE(srv_dn);
SAFE_FREE(srv_cn_0);
+ /* build the ads mods */
+ ctx = talloc_init("nt_printer_publish_ads");
+ mods = ads_init_mods(ctx);
+
+ get_local_printer_publishing_data(ctx, &mods,
+ &printer->info_2->data);
+ ads_mod_str(ctx, &mods, SPOOL_REG_PRINTERNAME,
+ printer->info_2->sharename);
+
/* publish it */
- ads_rc = ads_add_printer_entry(ads, prt_dn, ctx, &mods);
- if (LDAP_ALREADY_EXISTS == ads_rc.err.rc)
- ads_rc = ads_mod_printer_entry(ads, prt_dn, ctx,&mods);
+ ads_rc = ads_mod_printer_entry(ads, prt_dn, ctx, &mods);
+ if (ads_rc.err.rc == LDAP_NO_SUCH_OBJECT)
+ 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)));
+ talloc_destroy(ctx);
+
/* retreive the guid and store it locally */
if (ADS_ERR_OK(ads_search_dn(ads, &res, prt_dn, attrs))) {
- ads_memfree(ads, prt_dn);
+ ZERO_STRUCT(guid);
ads_pull_guid(ads, res, &guid);
ads_msgfree(ads, res);
store_printer_guid(printer->info_2, guid);
- win_rc = mod_a_printer(*printer, 2);
+ win_rc = mod_a_printer(printer, 2);
}
- safe_free(prt_dn);
- ads_destroy(&ads);
-
- return WERR_OK;
+ SAFE_FREE(prt_dn);
+ return win_rc;
}
-WERROR unpublish_it(NT_PRINTER_INFO_LEVEL *printer)
+static WERROR nt_printer_unpublish_ads(ADS_STRUCT *ads,
+ NT_PRINTER_INFO_LEVEL *printer)
{
ADS_STATUS ads_rc;
- ADS_STRUCT *ads;
void *res;
char *prt_dn = NULL;
- WERROR win_rc;
- printer->info_2->attributes ^= PRINTER_ATTRIBUTE_PUBLISHED;
- win_rc = mod_a_printer(*printer, 2);
- if (!W_ERROR_IS_OK(win_rc)) {
- DEBUG(3, ("err %d saving data\n",
- W_ERROR_V(win_rc)));
- return win_rc;
- }
-
- ads = ads_init(NULL, NULL, 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);
+ DEBUG(5, ("unpublishing printer %s\n", printer->info_2->printername));
- /* 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)));
- ads_destroy(&ads);
- return WERR_ACCESS_DENIED;
- }
-
/* remove the printer from the directory */
ads_rc = ads_find_printer_on_server(ads, &res,
printer->info_2->sharename, global_myname());
+
if (ADS_ERR_OK(ads_rc) && ads_count_replies(ads, res)) {
prt_dn = ads_get_dn(ads, res);
- ads_msgfree(ads, res);
ads_rc = ads_del_dn(ads, prt_dn);
ads_memfree(ads, prt_dn);
}
- ads_destroy(&ads);
+ ads_msgfree(ads, res);
return WERR_OK;
}
WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action)
{
+ ADS_STATUS ads_rc;
+ ADS_STRUCT *ads = NULL;
NT_PRINTER_INFO_LEVEL *printer = NULL;
WERROR win_rc;
win_rc = get_a_printer(print_hnd, &printer, 2, lp_servicename(snum));
if (!W_ERROR_IS_OK(win_rc))
- return win_rc;
+ goto done;
- switch(action) {
+ switch (action) {
case SPOOL_DS_PUBLISH:
case SPOOL_DS_UPDATE:
- win_rc = publish_it(printer);
+ /* set the DsSpooler info and attributes */
+ if (!(map_nt_printer_info2_to_dsspooler(printer->info_2))) {
+ win_rc = WERR_NOMEM;
+ goto done;
+ }
+
+ printer->info_2->attributes |= PRINTER_ATTRIBUTE_PUBLISHED;
break;
case SPOOL_DS_UNPUBLISH:
- win_rc = unpublish_it(printer);
+ printer->info_2->attributes ^= PRINTER_ATTRIBUTE_PUBLISHED;
break;
default:
win_rc = WERR_NOT_SUPPORTED;
+ goto done;
+ }
+
+ win_rc = mod_a_printer(printer, 2);
+ if (!W_ERROR_IS_OK(win_rc)) {
+ DEBUG(3, ("err %d saving data\n", W_ERROR_V(win_rc)));
+ goto done;
+ }
+
+ ads = ads_init(NULL, NULL, 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 SPOOL_DS_PUBLISH:
+ case SPOOL_DS_UPDATE:
+ win_rc = nt_printer_publish_ads(ads, printer);
+ break;
+ case SPOOL_DS_UNPUBLISH:
+ win_rc = nt_printer_unpublish_ads(ads, printer);
+ break;
}
-
+done:
free_a_printer(&printer, 2);
+ ads_destroy(&ads);
return win_rc;
}
-BOOL is_printer_published(Printer_entry *print_hnd, int snum, GUID *guid)
+WERROR check_published_printers(void)
{
+ ADS_STATUS ads_rc;
+ ADS_STRUCT *ads = NULL;
+ int snum;
+ int n_services = lp_numservices();
NT_PRINTER_INFO_LEVEL *printer = NULL;
- REGVAL_CTR *ctr;
- REGISTRY_VALUE *guid_val;
- WERROR win_rc;
- int i;
+ ads = ads_init(NULL, NULL, 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);
- win_rc = get_a_printer(print_hnd, &printer, 2, lp_servicename(snum));
- if (!W_ERROR_IS_OK(win_rc))
- return False;
+ /* 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)));
+ ads_destroy(&ads);
+ return WERR_ACCESS_DENIED;
+ }
- if (!(printer->info_2->attributes & PRINTER_ATTRIBUTE_PUBLISHED))
- return False;
+ for (snum = 0; snum < n_services; snum++) {
+ if (!(lp_snum_ok(snum) && lp_print_ok(snum)))
+ continue;
- if ((i = lookup_printerkey(&printer->info_2->data,
- SPOOL_DSSPOOLER_KEY)) < 0)
- return False;
+ if (W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2,
+ lp_servicename(snum))) &&
+ (printer->info_2->attributes & PRINTER_ATTRIBUTE_PUBLISHED))
+ nt_printer_publish_ads(ads, printer);
- if (!(ctr = &printer->info_2->data.keys[i].values)) {
- return False;
+ free_a_printer(&printer, 2);
}
- if (!(guid_val = regval_ctr_getvalue(ctr, "objectGUID"))) {
+ ads_destroy(&ads);
+ return WERR_OK;
+}
+
+BOOL is_printer_published(Printer_entry *print_hnd, int snum,
+ struct uuid *guid)
+{
+ NT_PRINTER_INFO_LEVEL *printer = NULL;
+ REGVAL_CTR *ctr;
+ REGISTRY_VALUE *guid_val;
+ WERROR win_rc;
+ int i;
+
+ win_rc = get_a_printer(print_hnd, &printer, 2, lp_servicename(snum));
+
+ if (!W_ERROR_IS_OK(win_rc) ||
+ !(printer->info_2->attributes & PRINTER_ATTRIBUTE_PUBLISHED) ||
+ ((i = lookup_printerkey(&printer->info_2->data,
+ SPOOL_DSSPOOLER_KEY)) < 0) ||
+ !(ctr = &printer->info_2->data.keys[i].values) ||
+ !(guid_val = regval_ctr_getvalue(ctr, "objectGUID"))) {
+ free_a_printer(&printer, 2);
return False;
}
- if (regval_size(guid_val) == sizeof(GUID))
- memcpy(guid, regval_data_p(guid_val), sizeof(GUID));
+ /* fetching printer guids really ought to be a separate function.. */
+ if (guid && regval_size(guid_val) == sizeof(struct uuid))
+ memcpy(guid, regval_data_p(guid_val), sizeof(struct uuid));
+ free_a_printer(&printer, 2);
return True;
}
-
#else
WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action)
{
return WERR_OK;
}
-BOOL is_printer_published(Printer_entry *print_hnd, int snum, GUID *guid)
+
+WERROR check_published_printers(void)
+{
+ return WERR_OK;
+}
+
+BOOL is_printer_published(Printer_entry *print_hnd, int snum,
+ struct uuid *guid)
{
return False;
}
-#endif
+#endif /* HAVE_ADS */
+
/****************************************************************************
***************************************************************************/
/* check to see if there are any more registry values */
+ regval_p = NULL;
len += tdb_unpack(buf+len, buflen-len, "p", ®val_p);
if ( !regval_p )
break;
/*
* break of the keyname from the value name.
- * Should only be one '\' in the string returned.
+ * Valuenames can have embedded '\'s so be careful.
+ * only support one level of keys. See the
+ * "Konica Fiery S300 50C-K v1.1. enu" 2k driver.
+ * -- jerry
*/
- str = strrchr( string, '\\');
+ str = strchr_m( string, '\\');
/* Put in "PrinterDriverData" is no key specified */
/****************************************************************************
Get a default printer info 2 struct.
****************************************************************************/
-static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, const char *sharename)
+static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, const char *servername, const char* sharename)
{
int snum;
NT_PRINTER_INFO_LEVEL_2 info;
snum = lp_servicenumber(sharename);
- slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", get_called_name());
+ slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", servername);
slprintf(info.printername, sizeof(info.printername)-1, "\\\\%s\\%s",
- get_called_name(), sharename);
+ servername, sharename);
fstrcpy(info.sharename, sharename);
fstrcpy(info.portname, SAMBA_PRINTER_PORT_NAME);
/****************************************************************************
****************************************************************************/
-static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, const char *sharename)
+static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, const char *servername, const char *sharename)
{
pstring key;
NT_PRINTER_INFO_LEVEL_2 info;
- int len = 0;
+ int len = 0;
+ int snum = lp_servicenumber(sharename);
TDB_DATA kbuf, dbuf;
fstring printername;
char adevice[MAXDEVICENAME];
dbuf = tdb_fetch(tdb_printers, kbuf);
if (!dbuf.dptr)
- return get_a_printer_2_default(info_ptr, sharename);
+ return get_a_printer_2_default(info_ptr, servername, sharename);
len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff",
&info.attributes,
/* Samba has to have shared raw drivers. */
info.attributes |= PRINTER_ATTRIBUTE_SAMBA;
+ info.attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
/* Restore the stripped strings. */
- slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", get_called_name());
- slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", get_called_name(),
- info.printername);
+ slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", servername);
+
+ if ( lp_force_printername(snum) )
+ slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", servername, sharename );
+ else
+ slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", servername, info.printername);
+
fstrcpy(info.printername, printername);
len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
* See comments in get_a_printer_2_default()
*/
- if (lp_default_devmode(lp_servicenumber(sharename)) && !info.devmode) {
+ if (lp_default_devmode(snum) && !info.devmode) {
DEBUG(8,("get_a_printer_2: Constructing a default device mode for [%s]\n",
printername));
info.devmode = construct_nt_devicemode(printername);
}
- safe_strcpy(adevice, info.printername, sizeof(adevice)-1);
+ slprintf( adevice, sizeof(adevice), "%s", info.printername );
if (info.devmode) {
fstrcpy(info.devmode->devicename, adevice);
}
/****************************************************************************
Debugging function, dump at level 6 the struct in the logs.
****************************************************************************/
-static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
+static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
{
uint32 result;
NT_PRINTER_INFO_LEVEL_2 *info2;
switch (level) {
case 2:
{
- if (printer.info_2 == NULL)
+ if (printer->info_2 == NULL)
result=5;
else
{
- info2=printer.info_2;
+ info2=printer->info_2;
DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
DEBUGADD(106,("priority:[%d]\n", info2->priority));
#endif
}
+/********************************************************************
+ Send a message to all smbds about the printer that just changed
+ ********************************************************************/
+
+static BOOL send_printer_mod_msg( char* printername )
+{
+ int len = strlen(printername);
+
+ if (!len)
+ return False;
+
+ DEBUG(10,("send_printer_mod_msg: Sending message about printer change [%s]\n",
+ printername));
+
+ /* spam everyone that we just changed this printer */
+
+ message_send_all( conn_tdb_ctx(), MSG_PRINTER_MOD, printername, len+1, False, NULL );
+
+ return True;
+}
+
/*
* The function below are the high level ones.
* only those ones must be called from the spoolss code.
Modify a printer. This is called from SETPRINTERDATA/DELETEPRINTERDATA.
****************************************************************************/
-WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
+WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
{
WERROR result;
* get_a_printer()
*/
- invalidate_printer_hnd_cache( printer.info_2->sharename );
+ invalidate_printer_hnd_cache( printer->info_2->sharename );
+ send_printer_mod_msg( printer->info_2->sharename );
switch (level) {
case 2:
of client's spoolss service in order for the
client's cache to show updates */
- printer.info_2->changeid = rev_changeid();
+ printer->info_2->changeid = rev_changeid();
/*
* Because one day someone will ask:
* 14/12/01 --jerry
*/
- result=update_a_printer_2(printer.info_2);
+ result=update_a_printer_2(printer->info_2);
break;
}
len += pack_values( &info->data, buf+len, buflen-len );
- if (buflen != len) {
+ if (buflen < len) {
char *tb;
- tb = (char *)Realloc(buf, len);
+ tb = (char *)SMB_REALLOC(buf, len);
if (!tb) {
DEBUG(0, ("update_driver_init_2: failed to enlarge buffer!\n"));
ret = -1;
Update (i.e. save) the driver init info (DEVMODE and values) for a printer
****************************************************************************/
-uint32 update_driver_init(NT_PRINTER_INFO_LEVEL printer, uint32 level)
+static uint32 update_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
{
uint32 result;
switch (level) {
case 2:
- result = update_driver_init_2(printer.info_2);
+ result = update_driver_init_2(printer->info_2);
break;
default:
result = 1;
if ((ctx = talloc_init("save_driver_init_2")) == NULL)
return WERR_NOMEM;
- if ((nt_devmode = (NT_DEVICEMODE*)malloc(sizeof(NT_DEVICEMODE))) == NULL) {
+ if ((nt_devmode = SMB_MALLOC_P(NT_DEVICEMODE)) == NULL) {
status = WERR_NOMEM;
goto done;
}
*
*/
- if ( update_driver_init(*printer, 2) != 0 ) {
+ if ( update_driver_init(printer, 2) != 0 ) {
DEBUG(10,("save_driver_init_2: error updating DEVMODE\n"));
status = WERR_NOMEM;
goto done;
* printer to match it. This allows initialization of the current printer
* as well as the driver.
*/
- status = mod_a_printer(*printer, 2);
+ status = mod_a_printer(printer, 2);
if (!W_ERROR_IS_OK(status)) {
DEBUG(10,("save_driver_init_2: error setting DEVMODE on printer [%s]\n",
printer->info_2->printername));
if ( !printer )
return NULL;
- if ( !(copy = (NT_PRINTER_INFO_LEVEL_2 *)malloc(sizeof(NT_PRINTER_INFO_LEVEL_2))) )
+ if ( !(copy = SMB_MALLOC_P(NT_PRINTER_INFO_LEVEL_2)) )
return NULL;
memcpy( copy, printer, sizeof(NT_PRINTER_INFO_LEVEL_2) );
/****************************************************************************
Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
+
+ Previously the code had a memory allocation problem because it always
+ used the TALLOC_CTX from the Printer_entry*. This context lasts
+ as a long as the original handle is open. So if the client made a lot
+ of getprinter[data]() calls, the memory usage would climb. Now we use
+ a short lived TALLOC_CTX for printer_info_2 objects returned. We
+ still use the Printer_entry->ctx for maintaining the cache copy though
+ since that object must live as long as the handle by definition.
+ --jerry
+
****************************************************************************/
WERROR get_a_printer( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level,
{
WERROR result;
NT_PRINTER_INFO_LEVEL *printer = NULL;
+ fstring servername;
*pp_printer = NULL;
switch (level) {
case 2:
- if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
+ if ((printer = SMB_MALLOC_P(NT_PRINTER_INFO_LEVEL)) == NULL) {
DEBUG(0,("get_a_printer: malloc fail.\n"));
return WERR_NOMEM;
}
ZERO_STRUCTP(printer);
+
+ if ( print_hnd )
+ fstrcpy( servername, print_hnd->servername );
+ else {
+ fstrcpy( servername, "%L" );
+ standard_sub_basic( "", servername, sizeof(servername)-1 );
+ }
/*
* check for cache first. A Printer handle cannot changed
&& (print_hnd->printer_type==PRINTER_HANDLE_IS_PRINTER)
&& print_hnd->printer_info )
{
- if ( !(printer->info_2 = dup_printer_2(print_hnd->ctx, print_hnd->printer_info->info_2)) ) {
+ /* get_talloc_ctx() works here because we need a short
+ lived talloc context */
+
+ if ( !(printer->info_2 = dup_printer_2(get_talloc_ctx(), print_hnd->printer_info->info_2)) )
+ {
DEBUG(0,("get_a_printer: unable to copy cached printer info!\n"));
SAFE_FREE(printer);
break;
}
- /* no cache for this handle; see if we can match one from another handle */
-
+ /* no cache for this handle; see if we can match one from another handle.
+ Make sure to use a short lived talloc ctx */
+
if ( print_hnd )
- result = find_printer_in_print_hnd_cache(print_hnd->ctx, &printer->info_2, sharename);
+ result = find_printer_in_print_hnd_cache(get_talloc_ctx(), &printer->info_2, servername, sharename);
/* fail to disk if we don't have it with any open handle */
if ( !print_hnd || !W_ERROR_IS_OK(result) )
- result = get_a_printer_2(&printer->info_2, sharename);
+ result = get_a_printer_2(&printer->info_2, servername, sharename );
/* we have a new printer now. Save it with this handle */
if ( W_ERROR_IS_OK(result) ) {
- dump_a_printer(*printer, level);
+ dump_a_printer(printer, level);
/* save a copy in cache */
if ( print_hnd && (print_hnd->printer_type==PRINTER_HANDLE_IS_PRINTER)) {
if ( !print_hnd->printer_info )
- print_hnd->printer_info = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL));
+ print_hnd->printer_info = SMB_MALLOC_P(NT_PRINTER_INFO_LEVEL);
if ( print_hnd->printer_info ) {
+ /* make sure to use the handle's talloc ctx here since
+ the printer_2 object must last until the handle is closed */
+
print_hnd->printer_info->info_2 = dup_printer_2(print_hnd->ctx, printer->info_2);
/* don't fail the lookup just because the cache update failed */
DATA_BLOB null_pw;
NTSTATUS nt_status;
fstring res_type;
+ BOOL bad_path;
+ SMB_STRUCT_STAT st;
if ( !info_3 )
return False;
if ( *info_3->driverpath ) {
if ( (s = strchr( &info_3->driverpath[1], '\\' )) != NULL ) {
+ driver_unix_convert(s, conn, NULL, &bad_path, &st);
DEBUG(10,("deleting driverfile [%s]\n", s));
unlink_internals(conn, 0, s);
}
if ( *info_3->configfile ) {
if ( (s = strchr( &info_3->configfile[1], '\\' )) != NULL ) {
+ driver_unix_convert(s, conn, NULL, &bad_path, &st);
DEBUG(10,("deleting configfile [%s]\n", s));
unlink_internals(conn, 0, s);
}
if ( *info_3->datafile ) {
if ( (s = strchr( &info_3->datafile[1], '\\' )) != NULL ) {
+ driver_unix_convert(s, conn, NULL, &bad_path, &st);
DEBUG(10,("deleting datafile [%s]\n", s));
unlink_internals(conn, 0, s);
}
if ( *info_3->helpfile ) {
if ( (s = strchr( &info_3->helpfile[1], '\\' )) != NULL ) {
+ driver_unix_convert(s, conn, NULL, &bad_path, &st);
DEBUG(10,("deleting helpfile [%s]\n", s));
unlink_internals(conn, 0, s);
}
/* bypass the "\print$" portion of the path */
if ( (file = strchr( info_3->dependentfiles[i]+1, '\\' )) != NULL ) {
+ driver_unix_convert(file, conn, NULL, &bad_path, &st);
DEBUG(10,("deleting dependent file [%s]\n", file));
unlink_internals(conn, 0, file );
}
print_job_delete, print_job_pause, print_job_resume,
print_queue_purge
+ Try access control in the following order (for performance reasons):
+ 1) root ans SE_PRINT_OPERATOR can do anything (easy check)
+ 2) check security descriptor (bit comparisons in memory)
+ 3) "printer admins" (may result in numerous calls to winbind)
+
****************************************************************************/
BOOL print_access_check(struct current_user *user, int snum, int access_type)
{
const char *pname;
TALLOC_CTX *mem_ctx = NULL;
extern struct current_user current_user;
+ 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 printer admins to do anything */
+ /* Always allow root or SE_PRINT_OPERATROR to do anything */
- if (user->uid == 0 ||
- user_in_list(uidtoname(user->uid), lp_printer_admin(snum), user->groups, user->ngroups)) {
+ if ( user->uid == 0 || user_has_privileges(user->nt_user_token, &se_printop ) ) {
return True;
}
DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE"));
+ /* see if we need to try the printer admin list */
+
+ if ( access_granted == 0 ) {
+ if ( user_in_list(uidtoname(user->uid), lp_printer_admin(snum), user->groups, user->ngroups) )
+ return True;
+ }
+
talloc_destroy(mem_ctx);
if (!result)
return ok;
}
+/****************************************************************************
+ Fill in the servername sent in the _spoolss_open_printer_ex() call
+****************************************************************************/
+char* get_server_name( Printer_entry *printer )
+{
+ return printer->servername;
+}