source: branches/samba-3.3.x/testsuite/printing/psec.c

Last change on this file was 206, checked in by Herwig Bauernfeind, 16 years ago

Import Samba 3.3 branch at 3.0.0 level (psmedley's port)

File size: 9.6 KB
Line 
1/*
2 Unix SMB/Netbios implementation.
3 Version 2.0
4
5 Printer security permission manipulation.
6
7 Copyright (C) Tim Potter 2000
8
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 3 of the License, or
12 (at your option) any later version.
13
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.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
21*/
22
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.
27
28 For this program to compile using the supplied Makefile.psec, Samba
29 must be configured with the --srcdir option
30
31 For getsec, output like the following is sent to standard output:
32
33 S-1-5-21-1067277791-1719175008-3000797951-500
34
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
42
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:
47
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
54
55 The above example describes the following permissions in order:
56
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
61
62 The setsec command takes the output format but sets the security descriptor
63 appropriately. */
64
65#include "includes.h"
66
67TDB_CONTEXT *tdb;
68
69/* ACE type conversions */
70
71char *ace_type_to_str(uint ace_type)
72{
73 static fstring temp;
74
75 switch(ace_type) {
76 case SEC_ACE_TYPE_ACCESS_DENIED:
77 return "DENY";
78 case SEC_ACE_TYPE_ACCESS_ALLOWED:
79 return "ALLOW";
80 }
81
82 slprintf(temp, sizeof(temp) - 1, "0x%02x", ace_type);
83 return temp;
84}
85
86uint str_to_ace_type(char *ace_type)
87{
88 if (strcmp(ace_type, "ALLOWED") == 0)
89 return SEC_ACE_TYPE_ACCESS_ALLOWED;
90
91 if (strcmp(ace_type, "DENIED") == 0)
92 return SEC_ACE_TYPE_ACCESS_DENIED;
93
94 return -1;
95}
96
97/* ACE mask (permission) conversions */
98
99char *ace_mask_to_str(uint32 ace_mask)
100{
101 static fstring temp;
102
103 switch (ace_mask) {
104 case PRINTER_ACE_FULL_CONTROL:
105 return "Full Control";
106 case PRINTER_ACE_MANAGE_DOCUMENTS:
107 return "Manage Documents";
108 case PRINTER_ACE_PRINT:
109 return "Print";
110 }
111
112 slprintf(temp, sizeof(temp) - 1, "0x%08x", ace_mask);
113 return temp;
114}
115
116uint32 str_to_ace_mask(char *ace_mask)
117{
118 if (strcmp(ace_mask, "Full Control") == 0)
119 return PRINTER_ACE_FULL_CONTROL;
120
121 if (strcmp(ace_mask, "Manage Documents") == 0)
122 return PRINTER_ACE_MANAGE_DOCUMENTS;
123
124 if (strcmp(ace_mask, "Print") == 0)
125 return PRINTER_ACE_PRINT;
126
127 return -1;
128}
129
130/* ACE conversions */
131
132char *ace_to_str(SEC_ACE *ace)
133{
134 static pstring temp;
135 fstring sidstr;
136
137 sid_to_string(sidstr, &ace->sid);
138
139 slprintf(temp, sizeof(temp) - 1, "%s %d %s %s",
140 ace_type_to_str(ace->type), ace->flags,
141 ace_mask_to_str(ace->info.mask), sidstr);
142
143 return temp;
144}
145
146void str_to_ace(SEC_ACE *ace, char *ace_str)
147{
148 SEC_ACCESS sa;
149 DOM_SID sid;
150 uint32 mask;
151 uint8 type, flags;
152
153 init_sec_access(&sa, mask);
154 init_sec_ace(ace, &sid, type, sa, flags);
155}
156
157/* Get a printer security descriptor */
158
159int psec_getsec(char *printer)
160{
161 SEC_DESC_BUF *secdesc_ctr = NULL;
162 TALLOC_CTX *mem_ctx = NULL;
163 fstring keystr, sidstr, tdb_path;
164 prs_struct ps;
165 int result = 0, i;
166
167 ZERO_STRUCT(ps);
168
169 /* Open tdb for reading */
170
171 slprintf(tdb_path, sizeof(tdb_path) - 1, "%s/ntdrivers.tdb",
172 lp_lockdir());
173
174 tdb = tdb_open(tdb_path, 0, 0, O_RDONLY, 0600);
175
176 if (!tdb) {
177 printf("psec: failed to open nt drivers database: %s\n",
178 sys_errlist[errno]);
179 return 1;
180 }
181
182 /* Get security blob from tdb */
183
184 slprintf(keystr, sizeof(keystr) - 1, "SECDESC/%s", printer);
185
186 mem_ctx = talloc_init();
187
188 if (!mem_ctx) {
189 printf("memory allocation error\n");
190 result = 1;
191 goto done;
192 }
193
194 if (tdb_prs_fetch(tdb, keystr, &ps, mem_ctx) != 0) {
195 printf("error fetching descriptor for printer %s\n",
196 printer);
197 /* cannot do a prs_mem_free() when tdb_prs_fetch fails */
198 /* as the prs structure has not been initialized */
199 tdb_close(tdb);
200 talloc_destroy(mem_ctx);
201 return 1;
202 }
203
204 /* Unpack into security descriptor buffer */
205
206 if (!sec_io_desc_buf("nt_printing_getsec", &secdesc_ctr, &ps, 1)) {
207 printf("error unpacking sec_desc_buf\n");
208 result = 1;
209 goto done;
210 }
211
212 /* Print owner and group sid */
213
214 if (secdesc_ctr->sec->owner_sid) {
215 sid_to_string(sidstr, secdesc_ctr->sec->owner_sid);
216 } else {
217 fstrcpy(sidstr, "");
218 }
219
220 printf("%s\n", sidstr);
221
222 if (secdesc_ctr->sec->grp_sid) {
223 sid_to_string(sidstr, secdesc_ctr->sec->grp_sid);
224 } else {
225 fstrcpy(sidstr, "");
226 }
227
228 printf("%s\n", sidstr);
229
230 /* Print aces */
231
232 if (!secdesc_ctr->sec->dacl) {
233 result = 0;
234 goto done;
235 }
236
237 for (i = 0; i < secdesc_ctr->sec->dacl->num_aces; i++) {
238 SEC_ACE *ace = &secdesc_ctr->sec->dacl->ace[i];
239
240 sid_to_string(sidstr, &ace->sid);
241
242 printf("%d %d 0x%08x %s\n", ace->type, ace->flags,
243 ace->info.mask, sidstr);
244 }
245
246 done:
247 if (tdb) tdb_close(tdb);
248 if (mem_ctx) talloc_destroy(mem_ctx);
249 if (secdesc_ctr) free_sec_desc_buf(&secdesc_ctr);
250 prs_mem_free(&ps);
251
252 return result;
253}
254
255/* Set a printer security descriptor */
256
257int psec_setsec(char *printer)
258{
259 DOM_SID user_sid, group_sid;
260 SEC_ACE *ace_list = NULL;
261 SEC_ACL *dacl = NULL;
262 SEC_DESC *sd;
263 SEC_DESC_BUF *sdb = NULL;
264 int result = 0, num_aces = 0;
265 fstring line, keystr, tdb_path;
266 size_t size;
267 prs_struct ps;
268 TALLOC_CTX *mem_ctx = NULL;
269 BOOL has_user_sid = False, has_group_sid = False;
270
271 ZERO_STRUCT(ps);
272
273 /* Open tdb for reading */
274
275 slprintf(tdb_path, sizeof(tdb_path) - 1, "%s/ntdrivers.tdb",
276 lp_lockdir());
277
278 tdb = tdb_open(tdb_path, 0, 0, O_RDWR, 0600);
279
280 if (!tdb) {
281 printf("psec: failed to open nt drivers database: %s\n",
282 sys_errlist[errno]);
283 result = 1;
284 goto done;
285 }
286
287 /* Read owner and group sid */
288
289 fgets(line, sizeof(fstring), stdin);
290 if (line[0] != '\n') {
291 string_to_sid(&user_sid, line);
292 has_user_sid = True;
293 }
294
295 fgets(line, sizeof(fstring), stdin);
296 if (line[0] != '\n') {
297 string_to_sid(&group_sid, line);
298 has_group_sid = True;
299 }
300
301 /* Read ACEs from standard input for discretionary ACL */
302
303 while(fgets(line, sizeof(fstring), stdin)) {
304 int ace_type, ace_flags;
305 uint32 ace_mask;
306 fstring sidstr;
307 DOM_SID sid;
308 SEC_ACCESS sa;
309
310 if (sscanf(line, "%d %d 0x%x %s", &ace_type, &ace_flags,
311 &ace_mask, sidstr) != 4) {
312 continue;
313 }
314
315 string_to_sid(&sid, sidstr);
316
317 ace_list = Realloc(ace_list, sizeof(SEC_ACE) *
318 (num_aces + 1));
319
320 init_sec_access(&sa, ace_mask);
321 init_sec_ace(&ace_list[num_aces], &sid, ace_type, sa,
322 ace_flags);
323
324 num_aces++;
325 }
326
327 dacl = make_sec_acl(ACL_REVISION, num_aces, ace_list);
328 free(ace_list);
329
330 /* Create security descriptor */
331
332 sd = make_sec_desc(SEC_DESC_REVISION,
333 has_user_sid ? &user_sid : NULL,
334 has_group_sid ? &group_sid : NULL,
335 NULL, /* System ACL */
336 dacl, /* Discretionary ACL */
337 &size);
338
339 free_sec_acl(&dacl);
340
341 sdb = make_sec_desc_buf(size, sd);
342
343 free_sec_desc(&sd);
344
345 /* Write security descriptor to tdb */
346
347 mem_ctx = talloc_init();
348
349 if (!mem_ctx) {
350 printf("memory allocation error\n");
351 result = 1;
352 goto done;
353 }
354
355 prs_init(&ps, (uint32)sec_desc_size(sdb->sec) +
356 sizeof(SEC_DESC_BUF), 4, mem_ctx, MARSHALL);
357
358 if (!sec_io_desc_buf("nt_printing_setsec", &sdb, &ps, 1)) {
359 printf("sec_io_desc_buf failed\n");
360 goto done;
361 }
362
363 slprintf(keystr, sizeof(keystr) - 1, "SECDESC/%s", printer);
364
365 if (!tdb_prs_store(tdb, keystr, &ps)==0) {
366 printf("Failed to store secdesc for %s\n", printer);
367 goto done;
368 }
369
370 done:
371 if (tdb) tdb_close(tdb);
372 if (sdb) free_sec_desc_buf(&sdb);
373 if (mem_ctx) talloc_destroy(mem_ctx);
374 prs_mem_free(&ps);
375
376 return result;
377}
378
379/* Help */
380
381void usage(void)
382{
383 printf("Usage: psec getsec|setsec printername\n");
384}
385
386/* Main function */
387
388int main(int argc, char **argv)
389{
390 pstring servicesf = CONFIGFILE;
391
392 /* Argument check */
393
394 if (argc == 1) {
395 usage();
396 return 1;
397 }
398
399 /* Load smb.conf file */
400
401 charset_initialise();
402
403 if (!lp_load(servicesf,False,False,True)) {
404 fprintf(stderr, "Couldn't load confiuration file %s\n",
405 servicesf);
406 return 1;
407 }
408
409 /* Do commands */
410
411 if (strcmp(argv[1], "setsec") == 0) {
412
413 if (argc != 3) {
414 usage();
415 return 1;
416 }
417
418 return psec_setsec(argv[2]);
419 }
420
421 if (strcmp(argv[1], "getsec") == 0) {
422
423 if (argc != 3) {
424 usage();
425 return 1;
426 }
427
428 return psec_getsec(argv[2]);
429 }
430
431 /* An unknown command */
432
433 printf("psec: unknown command %s\n", argv[1]);
434 return 1;
435}
Note: See TracBrowser for help on using the repository browser.