mirror of
https://github.com/samba-team/samba.git
synced 2025-02-02 09:47:23 +03:00
getting and setting security descriptors on printers now works
this needed some fixes in tdb_unpack(). Tim, you'll need to update (This used to be commit 9422719ab4c35e4ce3199b62dd632433bf391283)
This commit is contained in:
parent
712a30ed51
commit
5f7c40f6d0
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,5 @@
|
||||
/* this code is broken - there is a race condition with the unlink (tridge) */
|
||||
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
|
@ -768,7 +768,6 @@ static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
|
||||
free_nt_printer_param(&tofree);
|
||||
}
|
||||
|
||||
free(info);
|
||||
*info_ptr = NULL;
|
||||
}
|
||||
|
||||
@ -782,7 +781,7 @@ static int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
|
||||
|
||||
ZERO_STRUCT(devmode);
|
||||
|
||||
len += tdb_unpack(buf+len, buflen-len, "p", *nt_devmode);
|
||||
len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
|
||||
|
||||
if (!*nt_devmode) return len;
|
||||
|
||||
@ -860,7 +859,6 @@ static uint32 get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstrin
|
||||
int snum;
|
||||
NT_PRINTER_INFO_LEVEL_2 info;
|
||||
NT_DEVICEMODE devmode;
|
||||
SMB_STRUCT_STAT sbuf;
|
||||
|
||||
ZERO_STRUCT(info);
|
||||
ZERO_STRUCT(devmode);
|
||||
@ -878,16 +876,7 @@ static uint32 get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstrin
|
||||
|
||||
info.devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
|
||||
|
||||
/*
|
||||
* put a better system here, please.
|
||||
*/
|
||||
sbuf.st_mode = 0777;
|
||||
sbuf.st_uid = -1;
|
||||
sbuf.st_gid = -1;
|
||||
info.secdesc.len = convertperms_unix_to_sd(&sbuf, False,
|
||||
0777,
|
||||
&info.secdesc.sec);
|
||||
info.secdesc.max_len = info.secdesc.len;
|
||||
nt_printing_getsec(sharename, &info.secdesc);
|
||||
|
||||
*info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
|
||||
if (! *info_ptr) return 2;
|
||||
@ -939,11 +928,10 @@ static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharen
|
||||
info.parameters);
|
||||
|
||||
len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
|
||||
#if 0
|
||||
len += unpack_secdesc(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
|
||||
#endif
|
||||
len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
|
||||
|
||||
nt_printing_getsec(sharename, &info.secdesc);
|
||||
|
||||
*info_ptr=memdup(&info, sizeof(info));
|
||||
|
||||
return 0;
|
||||
@ -1299,6 +1287,63 @@ void init_devicemode(NT_DEVICEMODE *nt_devmode)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
store a security desc for a printer
|
||||
****************************************************************************/
|
||||
uint32 nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
|
||||
{
|
||||
prs_struct ps;
|
||||
fstring key;
|
||||
uint32 status;
|
||||
|
||||
prs_init(&ps, 0, 4, MARSHALL);
|
||||
ps.is_dynamic = True;
|
||||
|
||||
if (!sec_io_desc_buf("nt_printing_setsec", secdesc_ctr, &ps, 1)) {
|
||||
status = ERROR_INVALID_FUNCTION;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
slprintf(key, sizeof(key), "SECDESC/%s", printername);
|
||||
|
||||
if (tdb_prs_store(tdb, key, &ps)==0) {
|
||||
status = 0;
|
||||
} else {
|
||||
DEBUG(1,("Failed to store secdesc for %s\n", printername));
|
||||
status = ERROR_INVALID_FUNCTION;
|
||||
}
|
||||
|
||||
out:
|
||||
prs_mem_free(&ps);
|
||||
return status;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
get a security desc for a printer
|
||||
****************************************************************************/
|
||||
uint32 nt_printing_getsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
|
||||
{
|
||||
prs_struct ps;
|
||||
fstring key;
|
||||
|
||||
slprintf(key, sizeof(key), "SECDESC/%s", printername);
|
||||
|
||||
if (tdb_prs_fetch(tdb, key, &ps)!=0 ||
|
||||
!sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
|
||||
DEBUG(4,("using default secdesc for %s\n", printername));
|
||||
secdesc_ctr->len = convertperms_unix_to_sd(NULL, False,
|
||||
0007,
|
||||
&secdesc_ctr->sec);
|
||||
secdesc_ctr->max_len = secdesc_ctr->len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
prs_mem_free(&ps);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* error code:
|
||||
0: everything OK
|
||||
1: level not implemented
|
||||
|
@ -498,14 +498,8 @@ static BOOL api_spoolss_setprinter(prs_struct *data, prs_struct *rdata)
|
||||
}
|
||||
|
||||
r_u.status = _spoolss_setprinter(&q_u.handle, q_u.level, &q_u.info,
|
||||
q_u.devmode_ctr, q_u.command);
|
||||
|
||||
/* now, we can free the memory */
|
||||
if (q_u.info.level==2 && q_u.info.info_ptr!=0)
|
||||
safe_free(q_u.info.info_2);
|
||||
|
||||
if (q_u.devmode_ctr.devmode_ptr!=0)
|
||||
safe_free(q_u.devmode_ctr.devmode);
|
||||
q_u.devmode_ctr, &q_u.secdesc_ctr,
|
||||
q_u.command);
|
||||
|
||||
if(!spoolss_io_r_setprinter("",&r_u,rdata,0)) {
|
||||
DEBUG(0,("spoolss_io_r_setprinter: unable to marshall SPOOL_R_SETPRINTER.\n"));
|
||||
|
@ -2620,9 +2620,6 @@ static void construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum,
|
||||
get_a_printer_driver(&driver, 3, printer.info_2->drivername, architecture);
|
||||
|
||||
fill_printer_driver_info_3(info, driver, servername, architecture);
|
||||
|
||||
free_a_printer_driver(driver, 3);
|
||||
free_a_printer(printer, 2);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -2929,6 +2926,23 @@ static uint32 control_printer(const POLICY_HND *handle, uint32 command)
|
||||
return ERROR_INVALID_FUNCTION;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* called by spoolss_api_setprinter
|
||||
* when updating a printer description
|
||||
********************************************************************/
|
||||
static uint32 update_printer_sec(const POLICY_HND *handle, uint32 level,
|
||||
const SPOOL_PRINTER_INFO_LEVEL *info,
|
||||
const SEC_DESC_BUF *secdesc_ctr)
|
||||
{
|
||||
Printer_entry *Printer = find_printer_index_by_hnd(handle);
|
||||
|
||||
if (!OPEN_HANDLE(Printer))
|
||||
return ERROR_INVALID_HANDLE;
|
||||
|
||||
return nt_printing_setsec(Printer->dev.printername, secdesc_ctr);
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* called by spoolss_api_setprinter
|
||||
* when updating a printer description
|
||||
@ -3002,6 +3016,7 @@ static uint32 update_printer(const POLICY_HND *handle, uint32 level,
|
||||
uint32 _spoolss_setprinter(const POLICY_HND *handle, uint32 level,
|
||||
const SPOOL_PRINTER_INFO_LEVEL *info,
|
||||
const DEVMODE_CTR devmode_ctr,
|
||||
const SEC_DESC_BUF *secdesc_ctr,
|
||||
uint32 command)
|
||||
{
|
||||
Printer_entry *Printer = find_printer_index_by_hnd(handle);
|
||||
@ -3017,6 +3032,9 @@ uint32 _spoolss_setprinter(const POLICY_HND *handle, uint32 level,
|
||||
case 2:
|
||||
return update_printer(handle, level, info, devmode_ctr.devmode);
|
||||
break;
|
||||
case 3:
|
||||
return update_printer_sec(handle, level, info, secdesc_ctr);
|
||||
break;
|
||||
default:
|
||||
return ERROR_INVALID_LEVEL;
|
||||
break;
|
||||
|
@ -194,13 +194,13 @@ int tdb_unpack(char *buf, int bufsize, char *fmt, ...)
|
||||
case 'd':
|
||||
len = 4;
|
||||
d = va_arg(ap, uint32 *);
|
||||
if (bufsize >= len) goto no_space;
|
||||
if (bufsize < len) goto no_space;
|
||||
*d = IVAL(buf, 0);
|
||||
break;
|
||||
case 'p':
|
||||
len = 4;
|
||||
p = va_arg(ap, void **);
|
||||
if (bufsize >= len) goto no_space;
|
||||
if (bufsize < len) goto no_space;
|
||||
*p = (void *)IVAL(buf, 0);
|
||||
break;
|
||||
case 'f':
|
||||
@ -213,14 +213,14 @@ int tdb_unpack(char *buf, int bufsize, char *fmt, ...)
|
||||
i = va_arg(ap, int *);
|
||||
b = va_arg(ap, char **);
|
||||
len = 4;
|
||||
if (bufsize >= len) {
|
||||
*i = IVAL(buf, 0);
|
||||
len += *i;
|
||||
if (bufsize >= len) {
|
||||
*b = (char *)malloc(*i);
|
||||
memcpy(*b, buf+4, *i);
|
||||
}
|
||||
}
|
||||
if (bufsize < len) goto no_space;
|
||||
*i = IVAL(buf, 0);
|
||||
if (! *i) break;
|
||||
len += *i;
|
||||
if (bufsize < len) goto no_space;
|
||||
*b = (char *)malloc(*i);
|
||||
if (! *b) goto no_space;
|
||||
memcpy(*b, buf+4, *i);
|
||||
break;
|
||||
default:
|
||||
DEBUG(0,("Unknown tdb_unpack format %c in %s\n",
|
||||
@ -240,3 +240,35 @@ int tdb_unpack(char *buf, int bufsize, char *fmt, ...)
|
||||
}
|
||||
|
||||
|
||||
/* useful function to store a structure in rpc wire format */
|
||||
int tdb_prs_store(TDB_CONTEXT *tdb, char *keystr, prs_struct *ps)
|
||||
{
|
||||
TDB_DATA kbuf, dbuf;
|
||||
kbuf.dptr = keystr;
|
||||
kbuf.dsize = strlen(keystr)+1;
|
||||
dbuf.dptr = ps->data_p;
|
||||
dbuf.dsize = ps->data_offset;
|
||||
|
||||
return tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
|
||||
}
|
||||
|
||||
/* useful function to fetch a structure into rpc wire format */
|
||||
int tdb_prs_fetch(TDB_CONTEXT *tdb, char *keystr, prs_struct *ps)
|
||||
{
|
||||
TDB_DATA kbuf, dbuf;
|
||||
kbuf.dptr = keystr;
|
||||
kbuf.dsize = strlen(keystr)+1;
|
||||
|
||||
dbuf = tdb_fetch(tdb, kbuf);
|
||||
if (!dbuf.dptr) return -1;
|
||||
|
||||
ZERO_STRUCTP(ps);
|
||||
ps->io = UNMARSHALL;
|
||||
ps->align = 4;
|
||||
ps->data_p = dbuf.dptr;
|
||||
ps->data_offset = 0;
|
||||
ps->buffer_size = dbuf.dsize;
|
||||
ps->grow_size = dbuf.dsize;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user