update copyright notice since it we are now almost 4 months into 2003
[Samba.git] / testsuite / printing / psec.c
blobf86b5aca8f638b3d18e46c38ec826dfca455e641
1 /*
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:
48 Column Description
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
63 appropriately. */
65 #include "includes.h"
67 TDB_CONTEXT *tdb;
69 #if 0 /* Unused */
71 /* ACE type conversions */
73 char *ace_type_to_str(uint ace_type)
75 static fstring temp;
77 switch(ace_type) {
78 case SEC_ACE_TYPE_ACCESS_DENIED:
79 return "DENY";
80 case SEC_ACE_TYPE_ACCESS_ALLOWED:
81 return "ALLOW";
84 slprintf(temp, sizeof(temp) - 1, "0x%02x", ace_type);
85 return temp;
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;
96 return -1;
99 /* ACE mask (permission) conversions */
101 char *ace_mask_to_str(uint32 ace_mask)
103 static fstring temp;
105 switch (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:
111 return "Print";
114 slprintf(temp, sizeof(temp) - 1, "0x%08x", ace_mask);
115 return temp;
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;
129 return -1;
132 /* ACE conversions */
134 char *ace_to_str(SEC_ACE *ace)
136 static pstring temp;
137 fstring sidstr;
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);
145 return temp;
148 void str_to_ace(SEC_ACE *ace, char *ace_str)
150 SEC_ACCESS sa;
151 DOM_SID sid;
152 uint32 mask;
153 uint8 type, flags;
155 init_sec_access(&sa, mask);
156 init_sec_ace(ace, &sid, type, sa, flags);
159 #endif /* unused */
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;
168 prs_struct ps;
169 int result = 0, i;
171 ZERO_STRUCT(ps);
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);
178 if (!tdb) {
179 printf("psec: failed to open nt printers database: %s\n",
180 sys_errlist[errno]);
181 return 1;
184 /* Get security blob from tdb */
186 slprintf(keystr, sizeof(keystr) - 1, "SECDESC/%s", printer);
188 mem_ctx = talloc_init();
190 if (!mem_ctx) {
191 printf("memory allocation error\n");
192 result = 1;
193 goto done;
196 if (tdb_prs_fetch(tdb, keystr, &ps, mem_ctx) != 0) {
197 printf("error fetching descriptor for printer %s\n",
198 printer);
199 result = 1;
200 goto done;
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");
207 result = 1;
208 goto done;
211 /* Print owner and group sid */
213 if (secdesc_ctr->sec->owner_sid) {
214 sid_to_string(sidstr, secdesc_ctr->sec->owner_sid);
215 } else {
216 fstrcpy(sidstr, "");
219 printf("%s\n", sidstr);
221 if (secdesc_ctr->sec->grp_sid) {
222 sid_to_string(sidstr, secdesc_ctr->sec->grp_sid);
223 } else {
224 fstrcpy(sidstr, "");
227 printf("%s\n", sidstr);
229 /* Print aces */
231 if (!secdesc_ctr->sec->dacl) {
232 result = 0;
233 goto done;
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);
245 done:
246 if (tdb) tdb_close(tdb);
247 if (mem_ctx) talloc_destroy(mem_ctx);
248 prs_mem_free(&ps);
250 return result;
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;
260 SEC_DESC *sd;
261 SEC_DESC_BUF *sdb = NULL;
262 int result = 0, num_aces = 0;
263 fstring line, keystr, tdb_path;
264 size_t size;
265 prs_struct ps;
266 TALLOC_CTX *mem_ctx = NULL;
267 BOOL has_user_sid = False, has_group_sid = False;
269 /* Init memory */
271 ZERO_STRUCT(ps);
273 if (!(mem_ctx = talloc_init())) {
274 printf("memory allocation error\n");
275 result = 1;
276 goto done;
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);
284 if (!tdb) {
285 printf("psec: failed to open nt printers database: %s\n",
286 sys_errlist[errno]);
287 result = 1;
288 goto done;
291 /* Read owner and group sid */
293 fgets(line, sizeof(fstring), stdin);
294 if (line[0] != '\n') {
295 string_to_sid(&user_sid, line);
296 has_user_sid = True;
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;
309 uint32 ace_mask;
310 fstring sidstr;
311 DOM_SID sid;
312 SEC_ACCESS sa;
314 if (sscanf(line, "%d %d 0x%x %s", &ace_type, &ace_flags,
315 &ace_mask, sidstr) != 4) {
316 continue;
319 string_to_sid(&sid, sidstr);
321 ace_list = Realloc(ace_list, sizeof(SEC_ACE) *
322 (num_aces + 1));
324 init_sec_access(&sa, ace_mask);
325 init_sec_ace(&ace_list[num_aces], &sid, ace_type, sa,
326 ace_flags);
328 num_aces++;
331 dacl = make_sec_acl(mem_ctx, ACL_REVISION, num_aces, ace_list);
332 free(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 */
341 &size);
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");
352 goto done;
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);
359 goto done;
362 done:
363 if (tdb) tdb_close(tdb);
364 if (mem_ctx) talloc_destroy(mem_ctx);
365 prs_mem_free(&ps);
367 return result;
370 /* Help */
372 void usage(void)
374 printf("Usage: psec getsec|setsec printername\n");
377 /* Main function */
379 int main(int argc, char **argv)
381 /* Argument check */
383 if (argc == 1) {
384 usage();
385 return 1;
388 /* Do commands */
390 if (strcmp(argv[1], "setsec") == 0) {
392 if (argc != 3) {
393 usage();
394 return 1;
397 return psec_setsec(argv[2]);
400 if (strcmp(argv[1], "getsec") == 0) {
402 if (argc != 3) {
403 usage();
404 return 1;
407 return psec_getsec(argv[2]);
410 /* An unknown command */
412 printf("psec: unknown command %s\n", argv[1]);
413 return 1;