2
Unix SMB/Netbios implementation.
5
Printer security permission manipulation.
7
Copyright (C) Tim Potter 2000
9
This program is free software; you can redistribute it and/or modify
10
it under the terms of the GNU General Public License as published by
11
the Free Software Foundation; either version 2 of the License, or
12
(at your option) any later version.
14
This program is distributed in the hope that it will be useful,
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
GNU General Public License for more details.
19
You should have received a copy of the GNU General Public License
20
along with this program; if not, write to the Free Software
21
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
/* This program can get or set NT printer security permissions from the
25
command line. Usage: psec getsec|setsec printername. You must have
26
write access to the ntdrivers.tdb file to set permissions and read
27
access to get permissions.
29
For this program to compile using the supplied Makefile.psec, Samba
30
must be configured with the --srcdir option
32
For getsec, output like the following is sent to standard output:
34
S-1-5-21-1067277791-1719175008-3000797951-500
36
1 9 0x10000000 S-1-5-21-1067277791-1719175008-3000797951-501
37
1 2 0x10000000 S-1-5-21-1067277791-1719175008-3000797951-501
38
0 9 0x10000000 S-1-5-21-1067277791-1719175008-3000797951-500
39
0 2 0x10000000 S-1-5-21-1067277791-1719175008-3000797951-500
40
0 9 0x10000000 S-1-5-21-1067277791-1719175008-3000797951-513
41
0 2 0x00020000 S-1-5-21-1067277791-1719175008-3000797951-513
42
0 2 0xe0000000 S-1-1-0
44
The first two lines describe the owner user and owner group of the printer.
45
If either of these lines are blank then the respective owner property is
46
not set. The remaining lines list the printer permissions or ACE entries,
47
one per line. Each column describes a different property of the ACE:
50
-------------------------------------------------------------------
51
1 ACE type (allow/deny etc) defined in rpc_secdes.h
52
2 ACE flags defined in rpc_secdes.h
53
3 ACE mask - printer ACE masks are defined in rpc_spoolss.h
54
4 SID the ACE applies to
56
The above example describes the following permissions in order:
58
- The guest user has No Access to the printer
59
- The domain administrator has Full Access
60
- Domain Users can Manage Documents
61
- Everyone has Print access
63
The setsec command takes the output format but sets the security descriptor
70
/* ACE type conversions */
72
char *ace_type_to_str(uint ace_type)
77
case SEC_ACE_TYPE_ACCESS_DENIED:
79
case SEC_ACE_TYPE_ACCESS_ALLOWED:
83
slprintf(temp, sizeof(temp) - 1, "0x%02x", ace_type);
87
uint str_to_ace_type(char *ace_type)
89
if (strcmp(ace_type, "ALLOWED") == 0)
90
return SEC_ACE_TYPE_ACCESS_ALLOWED;
92
if (strcmp(ace_type, "DENIED") == 0)
93
return SEC_ACE_TYPE_ACCESS_DENIED;
98
/* ACE mask (permission) conversions */
100
char *ace_mask_to_str(uint32 ace_mask)
105
case PRINTER_ACE_FULL_CONTROL:
106
return "Full Control";
107
case PRINTER_ACE_MANAGE_DOCUMENTS:
108
return "Manage Documents";
109
case PRINTER_ACE_PRINT:
113
slprintf(temp, sizeof(temp) - 1, "0x%08x", ace_mask);
117
uint32 str_to_ace_mask(char *ace_mask)
119
if (strcmp(ace_mask, "Full Control") == 0)
120
return PRINTER_ACE_FULL_CONTROL;
122
if (strcmp(ace_mask, "Manage Documents") == 0)
123
return PRINTER_ACE_MANAGE_DOCUMENTS;
125
if (strcmp(ace_mask, "Print") == 0)
126
return PRINTER_ACE_PRINT;
131
/* ACE conversions */
133
char *ace_to_str(SEC_ACE *ace)
138
sid_to_string(sidstr, &ace->sid);
140
slprintf(temp, sizeof(temp) - 1, "%s %d %s %s",
141
ace_type_to_str(ace->type), ace->flags,
142
ace_mask_to_str(ace->info.mask), sidstr);
147
void str_to_ace(SEC_ACE *ace, char *ace_str)
154
init_sec_access(&sa, mask);
155
init_sec_ace(ace, &sid, type, sa, flags);
158
/* Get a printer security descriptor */
160
int psec_getsec(char *printer)
162
SEC_DESC_BUF *secdesc_ctr = NULL;
163
TALLOC_CTX *mem_ctx = NULL;
164
fstring keystr, sidstr, tdb_path;
170
/* Open tdb for reading */
172
slprintf(tdb_path, sizeof(tdb_path) - 1, "%s/ntdrivers.tdb",
175
tdb = tdb_open(tdb_path, 0, 0, O_RDONLY, 0600);
178
printf("psec: failed to open nt drivers database: %s\n",
183
/* Get security blob from tdb */
185
slprintf(keystr, sizeof(keystr) - 1, "SECDESC/%s", printer);
187
mem_ctx = talloc_init();
190
printf("memory allocation error\n");
195
if (tdb_prs_fetch(tdb, keystr, &ps, mem_ctx) != 0) {
196
printf("error fetching descriptor for printer %s\n",
198
/* cannot do a prs_mem_free() when tdb_prs_fetch fails */
199
/* as the prs structure has not been initialized */
201
talloc_destroy(mem_ctx);
205
/* Unpack into security descriptor buffer */
207
if (!sec_io_desc_buf("nt_printing_getsec", &secdesc_ctr, &ps, 1)) {
208
printf("error unpacking sec_desc_buf\n");
213
/* Print owner and group sid */
215
if (secdesc_ctr->sec->owner_sid) {
216
sid_to_string(sidstr, secdesc_ctr->sec->owner_sid);
221
printf("%s\n", sidstr);
223
if (secdesc_ctr->sec->grp_sid) {
224
sid_to_string(sidstr, secdesc_ctr->sec->grp_sid);
229
printf("%s\n", sidstr);
233
if (!secdesc_ctr->sec->dacl) {
238
for (i = 0; i < secdesc_ctr->sec->dacl->num_aces; i++) {
239
SEC_ACE *ace = &secdesc_ctr->sec->dacl->ace[i];
241
sid_to_string(sidstr, &ace->sid);
243
printf("%d %d 0x%08x %s\n", ace->type, ace->flags,
244
ace->info.mask, sidstr);
248
if (tdb) tdb_close(tdb);
249
if (mem_ctx) talloc_destroy(mem_ctx);
250
if (secdesc_ctr) free_sec_desc_buf(&secdesc_ctr);
256
/* Set a printer security descriptor */
258
int psec_setsec(char *printer)
260
DOM_SID user_sid, group_sid;
261
SEC_ACE *ace_list = NULL;
262
SEC_ACL *dacl = NULL;
264
SEC_DESC_BUF *sdb = NULL;
265
int result = 0, num_aces = 0;
266
fstring line, keystr, tdb_path;
269
TALLOC_CTX *mem_ctx = NULL;
270
BOOL has_user_sid = False, has_group_sid = False;
274
/* Open tdb for reading */
276
slprintf(tdb_path, sizeof(tdb_path) - 1, "%s/ntdrivers.tdb",
279
tdb = tdb_open(tdb_path, 0, 0, O_RDWR, 0600);
282
printf("psec: failed to open nt drivers database: %s\n",
288
/* Read owner and group sid */
290
fgets(line, sizeof(fstring), stdin);
291
if (line[0] != '\n') {
292
string_to_sid(&user_sid, line);
296
fgets(line, sizeof(fstring), stdin);
297
if (line[0] != '\n') {
298
string_to_sid(&group_sid, line);
299
has_group_sid = True;
302
/* Read ACEs from standard input for discretionary ACL */
304
while(fgets(line, sizeof(fstring), stdin)) {
305
int ace_type, ace_flags;
311
if (sscanf(line, "%d %d 0x%x %s", &ace_type, &ace_flags,
312
&ace_mask, sidstr) != 4) {
316
string_to_sid(&sid, sidstr);
318
ace_list = Realloc(ace_list, sizeof(SEC_ACE) *
321
init_sec_access(&sa, ace_mask);
322
init_sec_ace(&ace_list[num_aces], &sid, ace_type, sa,
328
dacl = make_sec_acl(ACL_REVISION, num_aces, ace_list);
331
/* Create security descriptor */
333
sd = make_sec_desc(SEC_DESC_REVISION,
334
has_user_sid ? &user_sid : NULL,
335
has_group_sid ? &group_sid : NULL,
336
NULL, /* System ACL */
337
dacl, /* Discretionary ACL */
342
sdb = make_sec_desc_buf(size, sd);
346
/* Write security descriptor to tdb */
348
mem_ctx = talloc_init();
351
printf("memory allocation error\n");
356
prs_init(&ps, (uint32)sec_desc_size(sdb->sec) +
357
sizeof(SEC_DESC_BUF), 4, mem_ctx, MARSHALL);
359
if (!sec_io_desc_buf("nt_printing_setsec", &sdb, &ps, 1)) {
360
printf("sec_io_desc_buf failed\n");
364
slprintf(keystr, sizeof(keystr) - 1, "SECDESC/%s", printer);
366
if (!tdb_prs_store(tdb, keystr, &ps)==0) {
367
printf("Failed to store secdesc for %s\n", printer);
372
if (tdb) tdb_close(tdb);
373
if (sdb) free_sec_desc_buf(&sdb);
374
if (mem_ctx) talloc_destroy(mem_ctx);
384
printf("Usage: psec getsec|setsec printername\n");
389
int main(int argc, char **argv)
391
pstring servicesf = CONFIGFILE;
400
/* Load smb.conf file */
402
charset_initialise();
404
if (!lp_load(servicesf,False,False,True)) {
405
fprintf(stderr, "Couldn't load confiuration file %s\n",
412
if (strcmp(argv[1], "setsec") == 0) {
419
return psec_setsec(argv[2]);
422
if (strcmp(argv[1], "getsec") == 0) {
429
return psec_getsec(argv[2]);
432
/* An unknown command */
434
printf("psec: unknown command %s\n", argv[1]);