diff options
Diffstat (limited to 'source3/printing')
-rw-r--r-- | source3/printing/nt_printing.c | 106 | ||||
-rw-r--r-- | source3/printing/printing.c | 11 |
2 files changed, 42 insertions, 75 deletions
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 91679235cd..699ddc60b2 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -35,6 +35,15 @@ static TDB_CONTEXT *tdb; /* used for driver files */ #define DATABASE_VERSION 1 +/* Map generic permissions to printer object specific permissions */ + +struct generic_mapping printer_generic_mapping = { + PRINTER_READ, + PRINTER_WRITE, + PRINTER_EXECUTE, + PRINTER_ALL_ACCESS +}; + /* We need one default form to support our default printer. Msoft adds the forms it wants and in the ORDER it wants them (note: DEVMODE papersize is an array index). Letter is always first, so (for the current code) additions @@ -2833,11 +2842,16 @@ BOOL nt_printing_getsec(char *printername, SEC_DESC_BUF **secdesc_ctr) prs_struct ps; TALLOC_CTX *mem_ctx = NULL; fstring key; + char *temp; mem_ctx = talloc_init(); if (mem_ctx == NULL) return False; + if ((temp = strchr(printername + 2, '\\'))) { + printername = temp + 1; + } + /* Fetch security descriptor from tdb */ slprintf(key, sizeof(key), "SECDESC/%s", printername); @@ -2910,8 +2924,9 @@ BOOL nt_printing_getsec(char *printername, SEC_DESC_BUF **secdesc_ctr) sid_to_string(sid_str, &acl->ace[i].sid); - DEBUG(10, ("%s 0x%08x\n", sid_str, - acl->ace[i].info.mask)); + DEBUG(10, ("%s %d %d 0x%08x\n", sid_str, + acl->ace[i].type, acl->ace[i].flags, + acl->ace[i].info.mask)); } } @@ -2956,6 +2971,20 @@ jfm: I should use this comment for the text file to explain */ +/* Convert generic access rights to printer object specific access rights. + It turns out that NT4 security descriptors use generic access rights and + NT5 the object specific ones. */ + +void map_printer_permissions(SEC_DESC *sd) +{ + int i; + + for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) { + se_map_generic(&sd->dacl->ace[i].info.mask, + &printer_generic_mapping); + } +} + /**************************************************************************** Check a user has permissions to perform the given operation. We use some constants defined in include/rpc_spoolss.h that look relevant to check @@ -2969,7 +2998,7 @@ jfm: I should use this comment for the text file to explain PRINTER_ACCESS_USE: print_job_start - JOB_ACCESS_ADMINISTER: + PRINTER_ACCESS_ADMINISTER (should really be JOB_ACCESS_ADMINISTER): print_job_delete, print_job_pause, print_job_resume, print_queue_purge @@ -2977,7 +3006,7 @@ jfm: I should use this comment for the text file to explain BOOL print_access_check(struct current_user *user, int snum, int access_type) { SEC_DESC_BUF *secdesc = NULL; - uint32 access_granted, status, required_access = 0; + uint32 access_granted, status; BOOL result; char *pname; extern struct current_user current_user; @@ -3008,77 +3037,14 @@ BOOL print_access_check(struct current_user *user, int snum, int access_type) /* Get printer security descriptor */ nt_printing_getsec(pname, &secdesc); - - /* Check against NT4 ACE mask values. From observation these - values are: - - Access Type ACE Mask Constant - ------------------------------------- - Full Control 0x10000000 PRINTER_ACE_FULL_CONTROL - Print 0xe0000000 PRINTER_ACE_PRINT - Manage Documents 0x00020000 PRINTER_ACE_MANAGE_DOCUMENTS - */ - - switch (access_type) { - case PRINTER_ACCESS_USE: - required_access = PRINTER_ACE_PRINT; - break; - case PRINTER_ACCESS_ADMINISTER: - /* - * This should be set to PRINTER_ACE_FULL_CONTROL, not to - * (PRINTER_ACE_PRINT | PRINTER_ACE_MANAGE_DOCUMENTS). - * Doing the latter gives anyone with both PRINTER_ACE_PRINT - * and PRINTER_ACE_MANAGE_DOCUMENTS (in any combination of ACLs) - * full control over all printer functions. This isn't what - * we want. - */ - required_access = PRINTER_ACE_FULL_CONTROL; - break; - case JOB_ACCESS_ADMINISTER: - required_access = PRINTER_ACE_MANAGE_DOCUMENTS; - break; - default: - DEBUG(0, ("invalid value passed to print_access_check()\n")); - result = False; - goto done; - } - if ((result = se_access_check(secdesc->sec, user, required_access, - &access_granted, &status))) { - goto done; - } - - /* Check against NT5 ACE mask values. From observation these - values are: - - Access Type ACE Mask Constant - ------------------------------------- - Full Control 0x000f000c PRINTER_ACE_NT5_FULL_CONTROL - Print 0x00020008 PRINTER_ACE_NT5_PRINT - Manage Documents 0x00020000 PRINTER_ACE_NT5_MANAGE_DOCUMENTS - - NT5 likes to rewrite the security descriptor and change the ACE - masks from NT4 format to NT5 format making them unreadable by - NT4 clients. */ - - switch (access_type) { - case PRINTER_ACCESS_USE: - required_access = PRINTER_ACE_NT5_PRINT; - break; - case PRINTER_ACCESS_ADMINISTER: - required_access = PRINTER_ACE_NT5_FULL_CONTROL; - break; - case JOB_ACCESS_ADMINISTER: - required_access = PRINTER_ACE_NT5_MANAGE_DOCUMENTS; - break; - } - - result = se_access_check(secdesc->sec, user, required_access, + map_printer_permissions(secdesc->sec); + + result = se_access_check(secdesc->sec, user, access_type, &access_granted, &status); /* Check access */ - done: DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE")); /* Free mallocated memory */ diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 842b97f9c5..57d0c2b8a3 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -575,7 +575,7 @@ BOOL print_job_delete(struct current_user *user, int jobid, int *errcode) owns their job. */ if (!owner && - !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { + !print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) { DEBUG(3, ("delete denied by security descriptor\n")); *errcode = ERROR_ACCESS_DENIED; return False; @@ -617,7 +617,7 @@ BOOL print_job_pause(struct current_user *user, int jobid, int *errcode) owner = is_owner(user, jobid); if (!owner && - !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { + !print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) { DEBUG(3, ("pause denied by security descriptor\n")); *errcode = ERROR_ACCESS_DENIED; return False; @@ -668,7 +668,7 @@ BOOL print_job_resume(struct current_user *user, int jobid, int *errcode) owner = is_owner(user, jobid); if (!is_owner(user, jobid) && - !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { + !print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) { DEBUG(3, ("resume denied by security descriptor\n")); *errcode = ERROR_ACCESS_DENIED; return False; @@ -807,7 +807,7 @@ int print_job_start(struct current_user *user, int snum, char *jobname) return -1; } - if (print_queue_length(snum) > lp_maxprintjobs(snum)) { + if (lp_maxprintjobs(snum) && print_queue_length(snum) > lp_maxprintjobs(snum)) { errno = ENOSPC; return -1; } @@ -1202,7 +1202,8 @@ BOOL print_queue_purge(struct current_user *user, int snum, int *errcode) njobs = print_queue_status(snum, &queue, &status); for (i=0;i<njobs;i++) { - if (print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { + if (print_access_check(user, snum, + PRINTER_ACCESS_ADMINISTER)) { print_job_delete1(queue[i].job); } } |