mirror of
https://github.com/samba-team/samba.git
synced 2025-02-23 09:57:40 +03:00
NT printer permissions test program.
(This used to be commit 9af82423d2e5c6f873a906097a56c8ac6c5f8297)
This commit is contained in:
parent
83424f676e
commit
b5f75af6f9
1
testsuite/printing/.cvsignore
Normal file
1
testsuite/printing/.cvsignore
Normal file
@ -0,0 +1 @@
|
||||
psec
|
21
testsuite/printing/Makefile.psec
Normal file
21
testsuite/printing/Makefile.psec
Normal file
@ -0,0 +1,21 @@
|
||||
#
|
||||
# Makefile for psec utility
|
||||
#
|
||||
|
||||
#
|
||||
# NOTE: Samba must be configured with the --srcdir option before this Makefile
|
||||
# will work: ./configure --srcdir=`pwd`
|
||||
#
|
||||
# Compile with: make -f Makefile.psec psec
|
||||
#
|
||||
|
||||
psec_default: psec
|
||||
|
||||
include ../../source/Makefile
|
||||
|
||||
PSEC_OBJ1 = $(LIB_OBJ) $(PARAM_OBJ) $(UBIQX_OBJ) $(RPC_PARSE_OBJ) $(LIBSMB_OBJ)
|
||||
|
||||
PSEC_OBJS = $(PSEC_OBJ1:%=$(srcdir)/%)
|
||||
|
||||
psec: $(PSEC_OBJS) psec.o
|
||||
$(CC) -o $@ psec.o $(PSEC_OBJS)
|
411
testsuite/printing/psec.c
Normal file
411
testsuite/printing/psec.c
Normal file
@ -0,0 +1,411 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 2.0
|
||||
|
||||
Printer security permission manipulation.
|
||||
|
||||
Copyright (C) Tim Potter 2000
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* This program can get or set NT printer security permissions from the
|
||||
command line. Usage: psec getsec|setsec printername. You must have
|
||||
write access to the ntdrivers.tdb file to set permissions and read
|
||||
access to get permissions.
|
||||
|
||||
For this program to compile using the supplied Makefile.psec, Samba
|
||||
must be configured with the --srcdir option
|
||||
|
||||
For getsec, output like the following is sent to standard output:
|
||||
|
||||
S-1-5-21-1067277791-1719175008-3000797951-500
|
||||
|
||||
1 9 0x10000000 S-1-5-21-1067277791-1719175008-3000797951-501
|
||||
1 2 0x10000000 S-1-5-21-1067277791-1719175008-3000797951-501
|
||||
0 9 0x10000000 S-1-5-21-1067277791-1719175008-3000797951-500
|
||||
0 2 0x10000000 S-1-5-21-1067277791-1719175008-3000797951-500
|
||||
0 9 0x10000000 S-1-5-21-1067277791-1719175008-3000797951-513
|
||||
0 2 0x00020000 S-1-5-21-1067277791-1719175008-3000797951-513
|
||||
0 2 0xe0000000 S-1-1-0
|
||||
|
||||
The first two lines describe the owner user and owner group of the printer.
|
||||
If either of these lines are blank then the respective owner property is
|
||||
not set. The remaining lines list the printer permissions or ACE entries,
|
||||
one per line. Each column describes a different property of the ACE:
|
||||
|
||||
Column Description
|
||||
-------------------------------------------------------------------
|
||||
1 ACE type (allow/deny etc) defined in rpc_secdes.h
|
||||
2 ACE flags defined in rpc_secdes.h
|
||||
3 ACE mask - printer ACE masks are defined in rpc_spoolss.h
|
||||
4 SID the ACE applies to
|
||||
|
||||
The above example describes the following permissions in order:
|
||||
|
||||
- The guest user has No Access to the printer
|
||||
- The domain administrator has Full Access
|
||||
- Domain Users can Manage Documents
|
||||
- Everyone has Print access
|
||||
|
||||
The setsec command takes the output format but sets the security descriptor
|
||||
appropriately. */
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
TDB_CONTEXT *tdb;
|
||||
|
||||
/* ACE type conversions */
|
||||
|
||||
char *ace_type_to_str(uint ace_type)
|
||||
{
|
||||
fstring temp;
|
||||
|
||||
switch(ace_type) {
|
||||
case SEC_ACE_TYPE_ACCESS_DENIED:
|
||||
return "DENY";
|
||||
case SEC_ACE_TYPE_ACCESS_ALLOWED:
|
||||
return "ALLOW";
|
||||
}
|
||||
|
||||
slprintf(temp, sizeof(temp) - 1, "0x%02x", ace_type);
|
||||
return temp;
|
||||
}
|
||||
|
||||
uint str_to_ace_type(char *ace_type)
|
||||
{
|
||||
if (strcmp(ace_type, "ALLOWED") == 0)
|
||||
return SEC_ACE_TYPE_ACCESS_ALLOWED;
|
||||
|
||||
if (strcmp(ace_type, "DENIED") == 0)
|
||||
return SEC_ACE_TYPE_ACCESS_DENIED;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ACE mask (permission) conversions */
|
||||
|
||||
char *ace_mask_to_str(uint32 ace_mask)
|
||||
{
|
||||
fstring temp;
|
||||
|
||||
switch (ace_mask) {
|
||||
case PRINTER_ACE_FULL_CONTROL:
|
||||
return "Full Control";
|
||||
case PRINTER_ACE_MANAGE_DOCUMENTS:
|
||||
return "Manage Documents";
|
||||
case PRINTER_ACE_PRINT:
|
||||
return "Print";
|
||||
}
|
||||
|
||||
slprintf(temp, sizeof(temp) - 1, "0x%08x", ace_mask);
|
||||
return temp;
|
||||
}
|
||||
|
||||
uint32 str_to_ace_mask(char *ace_mask)
|
||||
{
|
||||
if (strcmp(ace_mask, "Full Control") == 0)
|
||||
return PRINTER_ACE_FULL_CONTROL;
|
||||
|
||||
if (strcmp(ace_mask, "Manage Documents") == 0)
|
||||
return PRINTER_ACE_MANAGE_DOCUMENTS;
|
||||
|
||||
if (strcmp(ace_mask, "Print") == 0)
|
||||
return PRINTER_ACE_PRINT;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ACE conversions */
|
||||
|
||||
char *ace_to_str(SEC_ACE *ace)
|
||||
{
|
||||
pstring temp;
|
||||
fstring sidstr;
|
||||
|
||||
sid_to_string(sidstr, &ace->sid);
|
||||
|
||||
slprintf(temp, sizeof(temp) - 1, "%s %d %s %s",
|
||||
ace_type_to_str(ace->type), ace->flags,
|
||||
ace_mask_to_str(ace->info.mask), sidstr);
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
int str_to_ace(SEC_ACE *ace, char *ace_str)
|
||||
{
|
||||
SEC_ACCESS sa;
|
||||
DOM_SID sid;
|
||||
uint32 mask;
|
||||
uint8 type, flags;
|
||||
|
||||
init_sec_access(&sa, mask);
|
||||
init_sec_ace(ace, &sid, type, sa, flags);
|
||||
}
|
||||
|
||||
/* Get a printer security descriptor */
|
||||
|
||||
int psec_getsec(char *printer)
|
||||
{
|
||||
SEC_DESC_BUF *secdesc_ctr = NULL;
|
||||
TALLOC_CTX *mem_ctx = NULL;
|
||||
fstring keystr, sidstr, tdb_path;
|
||||
prs_struct ps;
|
||||
int result = 0, i;
|
||||
|
||||
/* Open tdb for reading */
|
||||
|
||||
slprintf(tdb_path, "%s/ntdrivers.tdb", LOCKDIR);
|
||||
tdb = tdb_open(tdb_path, 0, 0, O_RDONLY, 0600);
|
||||
|
||||
if (!tdb) {
|
||||
printf("psec: failed to open nt drivers database: %s\n",
|
||||
sys_errlist[errno]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Get security blob from tdb */
|
||||
|
||||
slprintf(keystr, sizeof(keystr) - 1, "SECDESC/%s", printer);
|
||||
|
||||
mem_ctx = talloc_init();
|
||||
|
||||
if (!mem_ctx) {
|
||||
printf("memory allocation error\n");
|
||||
result = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (tdb_prs_fetch(tdb, keystr, &ps, mem_ctx) != 0) {
|
||||
printf("error fetching descriptor for printer %s\n",
|
||||
printer);
|
||||
result = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Unpack into security descriptor buffer */
|
||||
|
||||
if (!sec_io_desc_buf("nt_printing_getsec", &secdesc_ctr, &ps, 1)) {
|
||||
printf("error unpacking sec_desc_buf\n");
|
||||
result = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Print owner and group sid */
|
||||
|
||||
if (secdesc_ctr->sec->owner_sid) {
|
||||
sid_to_string(sidstr, secdesc_ctr->sec->owner_sid);
|
||||
} else {
|
||||
fstrcpy(sidstr, "");
|
||||
}
|
||||
|
||||
printf("%s\n", sidstr);
|
||||
|
||||
if (secdesc_ctr->sec->grp_sid) {
|
||||
sid_to_string(sidstr, secdesc_ctr->sec->grp_sid);
|
||||
} else {
|
||||
fstrcpy(sidstr, "");
|
||||
}
|
||||
|
||||
printf("%s\n", sidstr);
|
||||
|
||||
/* Print aces */
|
||||
|
||||
if (!secdesc_ctr->sec->dacl) {
|
||||
result = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
for (i = 0; i < secdesc_ctr->sec->dacl->num_aces; i++) {
|
||||
SEC_ACE *ace = &secdesc_ctr->sec->dacl->ace[i];
|
||||
fstring sidstr;
|
||||
|
||||
sid_to_string(sidstr, &ace->sid);
|
||||
|
||||
printf("%d %d 0x%08x %s\n", ace->type, ace->flags,
|
||||
ace->info.mask, sidstr);
|
||||
}
|
||||
|
||||
done:
|
||||
if (tdb) tdb_close(tdb);
|
||||
if (mem_ctx) talloc_destroy(mem_ctx);
|
||||
if (secdesc_ctr) free_sec_desc_buf(&secdesc_ctr);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Set a printer security descriptor */
|
||||
|
||||
int psec_setsec(char *printer)
|
||||
{
|
||||
DOM_SID user_sid, group_sid;
|
||||
SEC_ACE *ace_list = NULL;
|
||||
SEC_ACL *dacl;
|
||||
SEC_DESC *sd;
|
||||
SEC_DESC_BUF *sdb = NULL;
|
||||
int result = 0, num_aces = 0;
|
||||
fstring line, keystr, tdb_path;
|
||||
size_t size;
|
||||
prs_struct ps;
|
||||
TALLOC_CTX *mem_ctx = NULL;
|
||||
BOOL has_user_sid = False, has_group_sid = False;
|
||||
|
||||
/* Open tdb for reading */
|
||||
|
||||
slprintf(tdb_path, "%s/ntdrivers.tdb", LOCKDIR);
|
||||
tdb = tdb_open(tdb_path, 0, 0, O_RDWR, 0600);
|
||||
|
||||
if (!tdb) {
|
||||
printf("psec: failed to open nt drivers database: %s\n",
|
||||
sys_errlist[errno]);
|
||||
result = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Read owner and group sid */
|
||||
|
||||
fgets(line, sizeof(fstring), stdin);
|
||||
if (line[0] != '\n') {
|
||||
string_to_sid(&user_sid, line);
|
||||
has_user_sid = True;
|
||||
}
|
||||
|
||||
fgets(line, sizeof(fstring), stdin);
|
||||
if (line[0] != '\n') {
|
||||
string_to_sid(&group_sid, line);
|
||||
has_group_sid = True;
|
||||
}
|
||||
|
||||
/* Read ACEs from standard input for discretionary ACL */
|
||||
|
||||
while(fgets(line, sizeof(fstring), stdin)) {
|
||||
int ace_type, ace_flags;
|
||||
uint32 ace_mask;
|
||||
fstring sidstr;
|
||||
DOM_SID sid;
|
||||
SEC_ACCESS sa;
|
||||
|
||||
if (sscanf(line, "%d %d 0x%x %s", &ace_type, &ace_flags,
|
||||
&ace_mask, sidstr) != 4) {
|
||||
continue;
|
||||
}
|
||||
|
||||
string_to_sid(&sid, sidstr);
|
||||
|
||||
ace_list = Realloc(ace_list, sizeof(SEC_ACE) *
|
||||
(num_aces + 1));
|
||||
|
||||
init_sec_access(&sa, ace_mask);
|
||||
init_sec_ace(&ace_list[num_aces], &sid, ace_type, sa,
|
||||
ace_flags);
|
||||
|
||||
num_aces++;
|
||||
}
|
||||
|
||||
dacl = make_sec_acl(ACL_REVISION, num_aces, ace_list);
|
||||
free(ace_list);
|
||||
|
||||
/* Create security descriptor */
|
||||
|
||||
sd = make_sec_desc(SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE |
|
||||
SEC_DESC_DACL_PRESENT,
|
||||
has_user_sid ? &user_sid : NULL,
|
||||
has_group_sid ? &group_sid : NULL,
|
||||
NULL, /* System ACL */
|
||||
dacl, /* Discretionary ACL */
|
||||
&size);
|
||||
|
||||
sdb = make_sec_desc_buf(size, sd);
|
||||
|
||||
free_sec_desc(&sd);
|
||||
|
||||
/* Write security descriptor to tdb */
|
||||
|
||||
mem_ctx = talloc_init();
|
||||
|
||||
if (!mem_ctx) {
|
||||
printf("memory allocation error\n");
|
||||
result = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
prs_init(&ps, (uint32)sec_desc_size(sdb->sec) +
|
||||
sizeof(SEC_DESC_BUF), 4, mem_ctx, MARSHALL);
|
||||
|
||||
if (!sec_io_desc_buf("nt_printing_setsec", &sdb, &ps, 1)) {
|
||||
printf("sec_io_desc_buf failed\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
slprintf(keystr, sizeof(keystr) - 1, "SECDESC/%s", printer);
|
||||
|
||||
if (!tdb_prs_store(tdb, keystr, &ps)==0) {
|
||||
printf("Failed to store secdesc for %s\n", printer);
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
if (tdb) tdb_close(tdb);
|
||||
if (sdb) free_sec_desc_buf(&sdb);
|
||||
if (mem_ctx) talloc_destroy(mem_ctx);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Help */
|
||||
|
||||
void usage(void)
|
||||
{
|
||||
printf("Usage: psec getsec|setsec printername\n");
|
||||
}
|
||||
|
||||
/* Main function */
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
/* Argument check */
|
||||
|
||||
if (argc == 1) {
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Do commands */
|
||||
|
||||
if (strcmp(argv[1], "setsec") == 0) {
|
||||
|
||||
if (argc != 3) {
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
return psec_setsec(argv[2]);
|
||||
}
|
||||
|
||||
if (strcmp(argv[1], "getsec") == 0) {
|
||||
|
||||
if (argc != 3) {
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
return psec_getsec(argv[2]);
|
||||
}
|
||||
|
||||
/* An unknown command */
|
||||
|
||||
printf("psec: unknown command %s\n", argv[1]);
|
||||
return 1;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user