2 Unix SMB/Netbios implementation.
4 Printer security permission manipulation.
6 Copyright (C) Tim Potter 2000
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 /* This program can get or set NT printer security permissions from the
24 command line. Usage: psec getsec|setsec printername. You must have
25 write access to the ntdrivers.tdb file to set permissions and read
26 access to get permissions.
28 For this program to compile using the supplied Makefile.psec, Samba
29 must be configured with the --srcdir option
31 For getsec, output like the following is sent to standard output:
33 S-1-5-21-1067277791-1719175008-3000797951-500
35 1 9 0x10000000 S-1-5-21-1067277791-1719175008-3000797951-501
36 1 2 0x10000000 S-1-5-21-1067277791-1719175008-3000797951-501
37 0 9 0x10000000 S-1-5-21-1067277791-1719175008-3000797951-500
38 0 2 0x10000000 S-1-5-21-1067277791-1719175008-3000797951-500
39 0 9 0x10000000 S-1-5-21-1067277791-1719175008-3000797951-513
40 0 2 0x00020000 S-1-5-21-1067277791-1719175008-3000797951-513
41 0 2 0xe0000000 S-1-1-0
43 The first two lines describe the owner user and owner group of the printer.
44 If either of these lines are blank then the respective owner property is
45 not set. The remaining lines list the printer permissions or ACE entries,
46 one per line. Each column describes a different property of the ACE:
49 -------------------------------------------------------------------
50 1 ACE type (allow/deny etc) defined in rpc_secdes.h
51 2 ACE flags defined in rpc_secdes.h
52 3 ACE mask - printer ACE masks are defined in rpc_spoolss.h
53 4 SID the ACE applies to
55 The above example describes the following permissions in order:
57 - The guest user has No Access to the printer
58 - The domain administrator has Full Access
59 - Domain Users can Manage Documents
60 - Everyone has Print access
62 The setsec command takes the output format but sets the security descriptor
71 /* ACE type conversions */
73 char *ace_type_to_str(uint ace_type
)
78 case SEC_ACE_TYPE_ACCESS_DENIED
:
80 case SEC_ACE_TYPE_ACCESS_ALLOWED
:
84 slprintf(temp
, sizeof(temp
) - 1, "0x%02x", ace_type
);
88 uint
str_to_ace_type(char *ace_type
)
90 if (strcmp(ace_type
, "ALLOWED") == 0)
91 return SEC_ACE_TYPE_ACCESS_ALLOWED
;
93 if (strcmp(ace_type
, "DENIED") == 0)
94 return SEC_ACE_TYPE_ACCESS_DENIED
;
99 /* ACE mask (permission) conversions */
101 char *ace_mask_to_str(uint32 ace_mask
)
106 case PRINTER_ACE_FULL_CONTROL
:
107 return "Full Control";
108 case PRINTER_ACE_MANAGE_DOCUMENTS
:
109 return "Manage Documents";
110 case PRINTER_ACE_PRINT
:
114 slprintf(temp
, sizeof(temp
) - 1, "0x%08x", ace_mask
);
118 uint32
str_to_ace_mask(char *ace_mask
)
120 if (strcmp(ace_mask
, "Full Control") == 0)
121 return PRINTER_ACE_FULL_CONTROL
;
123 if (strcmp(ace_mask
, "Manage Documents") == 0)
124 return PRINTER_ACE_MANAGE_DOCUMENTS
;
126 if (strcmp(ace_mask
, "Print") == 0)
127 return PRINTER_ACE_PRINT
;
132 /* ACE conversions */
134 char *ace_to_str(SEC_ACE
*ace
)
139 sid_to_string(sidstr
, &ace
->trustee
);
141 slprintf(temp
, sizeof(temp
) - 1, "%s %d %s %s",
142 ace_type_to_str(ace
->type
), ace
->flags
,
143 ace_mask_to_str(ace
->info
.mask
), sidstr
);
148 void str_to_ace(SEC_ACE
*ace
, char *ace_str
)
155 init_sec_access(&sa
, mask
);
156 init_sec_ace(ace
, &sid
, type
, sa
, flags
);
161 /* Get a printer security descriptor */
163 int psec_getsec(char *printer
)
165 SEC_DESC_BUF
*secdesc_ctr
= NULL
;
166 TALLOC_CTX
*mem_ctx
= NULL
;
167 fstring keystr
, sidstr
, tdb_path
;
173 /* Open tdb for reading */
175 slprintf(tdb_path
, sizeof(tdb_path
) - 1, "%s/ntprinters.tdb", LOCKDIR
);
176 tdb
= tdb_open(tdb_path
, 0, 0, O_RDONLY
, 0600);
179 printf("psec: failed to open nt printers database: %s\n",
184 /* Get security blob from tdb */
186 slprintf(keystr
, sizeof(keystr
) - 1, "SECDESC/%s", printer
);
188 mem_ctx
= talloc_init();
191 printf("memory allocation error\n");
196 if (tdb_prs_fetch(tdb
, keystr
, &ps
, mem_ctx
) != 0) {
197 printf("error fetching descriptor for printer %s\n",
203 /* Unpack into security descriptor buffer */
205 if (!sec_io_desc_buf("nt_printing_getsec", &secdesc_ctr
, &ps
, 1)) {
206 printf("error unpacking sec_desc_buf\n");
211 /* Print owner and group sid */
213 if (secdesc_ctr
->sec
->owner_sid
) {
214 sid_to_string(sidstr
, secdesc_ctr
->sec
->owner_sid
);
219 printf("%s\n", sidstr
);
221 if (secdesc_ctr
->sec
->grp_sid
) {
222 sid_to_string(sidstr
, secdesc_ctr
->sec
->grp_sid
);
227 printf("%s\n", sidstr
);
231 if (!secdesc_ctr
->sec
->dacl
) {
236 for (i
= 0; i
< secdesc_ctr
->sec
->dacl
->num_aces
; i
++) {
237 SEC_ACE
*ace
= &secdesc_ctr
->sec
->dacl
->ace
[i
];
239 sid_to_string(sidstr
, &ace
->trustee
);
241 printf("%d %d 0x%08x %s\n", ace
->type
, ace
->flags
,
242 ace
->info
.mask
, sidstr
);
246 if (tdb
) tdb_close(tdb
);
247 if (mem_ctx
) talloc_destroy(mem_ctx
);
253 /* Set a printer security descriptor */
255 int psec_setsec(char *printer
)
257 DOM_SID user_sid
, group_sid
;
258 SEC_ACE
*ace_list
= NULL
;
259 SEC_ACL
*dacl
= NULL
;
261 SEC_DESC_BUF
*sdb
= NULL
;
262 int result
= 0, num_aces
= 0;
263 fstring line
, keystr
, tdb_path
;
266 TALLOC_CTX
*mem_ctx
= NULL
;
267 BOOL has_user_sid
= False
, has_group_sid
= False
;
273 if (!(mem_ctx
= talloc_init())) {
274 printf("memory allocation error\n");
279 /* Open tdb for reading */
281 slprintf(tdb_path
, sizeof(tdb_path
) - 1, "%s/ntprinters.tdb", LOCKDIR
);
282 tdb
= tdb_open(tdb_path
, 0, 0, O_RDWR
, 0600);
285 printf("psec: failed to open nt printers database: %s\n",
291 /* Read owner and group sid */
293 fgets(line
, sizeof(fstring
), stdin
);
294 if (line
[0] != '\n') {
295 string_to_sid(&user_sid
, line
);
299 fgets(line
, sizeof(fstring
), stdin
);
300 if (line
[0] != '\n') {
301 string_to_sid(&group_sid
, line
);
302 has_group_sid
= True
;
305 /* Read ACEs from standard input for discretionary ACL */
307 while(fgets(line
, sizeof(fstring
), stdin
)) {
308 int ace_type
, ace_flags
;
314 if (sscanf(line
, "%d %d 0x%x %s", &ace_type
, &ace_flags
,
315 &ace_mask
, sidstr
) != 4) {
319 string_to_sid(&sid
, sidstr
);
321 ace_list
= Realloc(ace_list
, sizeof(SEC_ACE
) *
324 init_sec_access(&sa
, ace_mask
);
325 init_sec_ace(&ace_list
[num_aces
], &sid
, ace_type
, sa
,
331 dacl
= make_sec_acl(mem_ctx
, ACL_REVISION
, num_aces
, ace_list
);
334 /* Create security descriptor */
336 sd
= make_sec_desc(mem_ctx
, SEC_DESC_REVISION
,
337 has_user_sid
? &user_sid
: NULL
,
338 has_group_sid
? &group_sid
: NULL
,
339 NULL
, /* System ACL */
340 dacl
, /* Discretionary ACL */
343 sdb
= make_sec_desc_buf(mem_ctx
, size
, sd
);
345 /* Write security descriptor to tdb */
347 prs_init(&ps
, (uint32
)sec_desc_size(sdb
->sec
) +
348 sizeof(SEC_DESC_BUF
), mem_ctx
, MARSHALL
);
350 if (!sec_io_desc_buf("nt_printing_setsec", &sdb
, &ps
, 1)) {
351 printf("sec_io_desc_buf failed\n");
355 slprintf(keystr
, sizeof(keystr
) - 1, "SECDESC/%s", printer
);
357 if (!tdb_prs_store(tdb
, keystr
, &ps
)==0) {
358 printf("Failed to store secdesc for %s\n", printer
);
363 if (tdb
) tdb_close(tdb
);
364 if (mem_ctx
) talloc_destroy(mem_ctx
);
374 printf("Usage: psec getsec|setsec printername\n");
379 int main(int argc
, char **argv
)
390 if (strcmp(argv
[1], "setsec") == 0) {
397 return psec_setsec(argv
[2]);
400 if (strcmp(argv
[1], "getsec") == 0) {
407 return psec_getsec(argv
[2]);
410 /* An unknown command */
412 printf("psec: unknown command %s\n", argv
[1]);