diff options
Diffstat (limited to 'testsuite/printing/psec.c')
-rw-r--r-- | testsuite/printing/psec.c | 411 |
1 files changed, 411 insertions, 0 deletions
diff --git a/testsuite/printing/psec.c b/testsuite/printing/psec.c new file mode 100644 index 0000000000..e3490de759 --- /dev/null +++ b/testsuite/printing/psec.c @@ -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; +} |