NT printer permissions test program.
authorTim Potter <tpot@samba.org>
Mon, 14 Aug 2000 18:39:51 +0000 (18:39 +0000)
committerTim Potter <tpot@samba.org>
Mon, 14 Aug 2000 18:39:51 +0000 (18:39 +0000)
(This used to be commit 9af82423d2e5c6f873a906097a56c8ac6c5f8297)

testsuite/printing/.cvsignore [new file with mode: 0644]
testsuite/printing/Makefile.psec [new file with mode: 0644]
testsuite/printing/psec.c [new file with mode: 0644]

diff --git a/testsuite/printing/.cvsignore b/testsuite/printing/.cvsignore
new file mode 100644 (file)
index 0000000..cdbd566
--- /dev/null
@@ -0,0 +1 @@
+psec
diff --git a/testsuite/printing/Makefile.psec b/testsuite/printing/Makefile.psec
new file mode 100644 (file)
index 0000000..810bc57
--- /dev/null
@@ -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)
diff --git a/testsuite/printing/psec.c b/testsuite/printing/psec.c
new file mode 100644 (file)
index 0000000..e3490de
--- /dev/null
@@ -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;
+}