r4805: Last planned change to the privileges infrastructure:
[samba.git] / source3 / printing / nt_printing.c
index b17ddb51caf5c346e0f074966a3bd8190d0c6d45..d22ec935a39cc737990614784aad31879581487a 100644 (file)
@@ -593,8 +593,7 @@ BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
        
        unistr2_to_ascii(form_name, &form->name, sizeof(form_name)-1);
        for (n=0; n<*count; n++) {
-               if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
-                       DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
+               if ( strequal((*list)[n].name, form_name) ) {
                        update=True;
                        break;
                }
@@ -618,6 +617,9 @@ BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
        (*list)[n].right=form->right;
        (*list)[n].bottom=form->bottom;
 
+       DEBUG(6,("add_a_form: Successfully %s form [%s]\n", 
+               update ? "updated" : "added", form_name));
+
        return True;
 }
 
@@ -2044,17 +2046,32 @@ static int pack_values(NT_PRINTER_DATA *data, char *buf, int buflen)
  handles are not affected.
 ****************************************************************************/
 
-uint32 del_a_printer(char *sharename)
+uint32 del_a_printer(const char *sharename)
 {
        pstring key;
        TDB_DATA kbuf;
+       pstring printdb_path;
 
        slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
-
        kbuf.dptr=key;
        kbuf.dsize=strlen(key)+1;
+       tdb_delete(tdb_printers, kbuf);
 
+       slprintf(key, sizeof(key)-1, "%s%s", SECDESC_PREFIX, sharename);
+       kbuf.dptr=key;
+       kbuf.dsize=strlen(key)+1;
        tdb_delete(tdb_printers, kbuf);
+
+       close_all_print_db();
+
+       if (geteuid() == 0) {
+               pstrcpy(printdb_path, lock_path("printing/"));
+               pstrcat(printdb_path, sharename);
+               pstrcat(printdb_path, ".tdb");
+
+               unlink(printdb_path);
+       }
+
        return 0;
 }
 
@@ -2897,7 +2914,8 @@ BOOL is_printer_published(Printer_entry *print_hnd, int snum,
                return False;
        }
 
-       if (regval_size(guid_val) == sizeof(struct uuid))
+       /* fetching printer guids really ought to be a separate function.. */
+       if (guid && regval_size(guid_val) == sizeof(struct uuid))
                memcpy(guid, regval_data_p(guid_val), sizeof(struct uuid));
 
        free_a_printer(&printer, 2);
@@ -5016,6 +5034,11 @@ void map_printer_permissions(SEC_DESC *sd)
        print_job_delete, print_job_pause, print_job_resume,
        print_queue_purge
 
+  Try access control in the following order (for performance reasons):
+    1)  root ans SE_PRINT_OPERATOR can do anything (easy check) 
+    2)  check security descriptor (bit comparisons in memory)
+    3)  "printer admins" (may result in numerous calls to winbind)
+
  ****************************************************************************/
 BOOL print_access_check(struct current_user *user, int snum, int access_type)
 {
@@ -5026,16 +5049,16 @@ BOOL print_access_check(struct current_user *user, int snum, int access_type)
        const char *pname;
        TALLOC_CTX *mem_ctx = NULL;
        extern struct current_user current_user;
+       SE_PRIV se_printop = SE_PRINT_OPERATOR;
        
        /* If user is NULL then use the current_user structure */
 
        if (!user)
                user = &current_user;
 
-       /* Always allow root or printer admins to do anything */
+       /* Always allow root or SE_PRINT_OPERATROR to do anything */
 
-       if (user->uid == 0 ||
-           user_in_list(uidtoname(user->uid), lp_printer_admin(snum), user->groups, user->ngroups)) {
+       if ( user->uid == 0 || user_has_privileges(user->nt_user_token, &se_printop ) ) {
                return True;
        }
 
@@ -5084,6 +5107,13 @@ BOOL print_access_check(struct current_user *user, int snum, int access_type)
 
        DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE"));
 
+        /* see if we need to try the printer admin list */
+
+        if ( access_granted == 0 ) {
+                if ( user_in_list(uidtoname(user->uid), lp_printer_admin(snum), user->groups, user->ngroups) )
+                        return True;
+        }
+
        talloc_destroy(mem_ctx);
        
        if (!result)