Fixed memory leak with NT tokens.
authorJeremy Allison <jra@samba.org>
Wed, 9 Aug 2000 18:40:48 +0000 (18:40 +0000)
committerJeremy Allison <jra@samba.org>
Wed, 9 Aug 2000 18:40:48 +0000 (18:40 +0000)
Added debug messages to se_access_check().
Added FULL_ACCESS acl to default acl on printers.
Jeremy.
(This used to be commit 7507f6f408cf8b0f8d7e2b3da54ce5fb5ef5343b)

source3/lib/util_seaccess.c
source3/printing/nt_printing.c
source3/smbd/sec_ctx.c
source3/smbd/uid.c

index 351e93dc7a38ac8b282a6c6ac4bee34d7553746f..354f7f2faee6a4f527e0f69bdad5c72de97e0043 100644 (file)
@@ -212,6 +212,9 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
        *status = NT_STATUS_NOPROBLEMO;
        *acc_granted = 0;
 
+       DEBUG(10,("se_access_check: requested access %x, for uid %u\n", 
+                               (unsigned int)acc_desired, (unsigned int)user->uid ));
+
        /*
         * No security descriptor or security descriptor with no DACL
         * present allows all access.
@@ -222,7 +225,7 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
        if (!sd || (sd && (!(sd->type & SEC_DESC_DACL_PRESENT) || sd->dacl == NULL))) {
                *status = NT_STATUS_NOPROBLEMO;
                *acc_granted = acc_desired;
-               DEBUG(3, ("se_access_check: no sd or blank DACL, access allowed\n"));
+               DEBUG(5, ("se_access_check: no sd or blank DACL, access allowed\n"));
                return True;
        }
 
@@ -233,6 +236,7 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
                DEBUG(1, ("no owner for security descriptor\n"));
                *acc_granted = 0;
                *status = NT_STATUS_ACCESS_DENIED;
+               DEBUG(5, ("se_access_check: no owner sid, access denied\n"));
                return False;
        }
 
@@ -260,9 +264,16 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
        }
 
        for ( i = 0 ; i < acl->num_aces && tmp_acc_desired != 0; i++) {
-               tmp_acc_desired = check_ace( &acl->ace[i], token, tmp_acc_desired, status);
+               SEC_ACE *ace = &acl->ace[i];
+
+               DEBUG(10,("se_access_check: ACE %u: SID = %s mask = %x, current desired = %x\n",
+                               (unsigned int)i, sid_to_string(sid_str, &ace->sid),
+                               (unsigned int) ace->info.mask, (unsigned int)tmp_acc_desired ));
+
+               tmp_acc_desired = check_ace( ace, token, tmp_acc_desired, status);
                if (*status != NT_STATUS_NOPROBLEMO) {
                        *acc_granted = 0;
+                       DEBUG(5,("se_access_check: ACE %u denied with status %x.\n", (unsigned int)i, (unsigned int)*status ));
                        return False;
                }
        }
@@ -275,10 +286,12 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
        if (tmp_acc_desired == 0) {
                *acc_granted = acc_desired;
                *status = NT_STATUS_NOPROBLEMO;
+               DEBUG(5,("se_access_check: access (%x) granted.\n", (unsigned int)acc_desired ));
                return True;
        }
                
        *acc_granted = 0;
        *status = NT_STATUS_ACCESS_DENIED;
+       DEBUG(5,("se_access_check: access (%x) denied.\n", (unsigned int)acc_desired ));
        return False;
 }
index 11c8e8027639c50e3aeb201479fc27ec6376d019..c88217cc7ef84b044296e5fc8295f41fe68a9145 100644 (file)
@@ -417,6 +417,7 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
                unbecome_root();
                return False;
        }
+       unbecome_root();
 
        /* Null password is ok - we are already an authenticated user... */
        *null_pw = '\0';
@@ -424,13 +425,18 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
 
        if (conn == NULL) {
                DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
-               unbecome_root();
                return False;
        }
 
+       /*
+        * Save who we are - we are temporarily becoming the connection user.
+        */
+
+       push_sec_ctx();
+
        if (!become_user(conn, conn->vuid)) {
                DEBUG(0,("move_driver_to_download_area: Can't become user %s\n", user_name ));
-               unbecome_root();
+               pop_sec_ctx();
                return False;
        }
 
@@ -461,62 +467,62 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
                DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
                                old_name, new_name ));
                close_cnum(conn, user->vuid);
-               unbecome_root();
+               pop_sec_ctx();
                return False;
        }
 
        if (!strequal(driver->datafile, driver->driverpath)) {
-       slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->datafile); 
-       slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->datafile);      
+               slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->datafile); 
+               slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->datafile);      
                if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
-               DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
-                               old_name, new_name ));
-               close_cnum(conn, user->vuid);
-               unbecome_root();
-               return False;
-       }
+                       DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
+                                       old_name, new_name ));
+                       close_cnum(conn, user->vuid);
+                       pop_sec_ctx();
+                       return False;
+               }
        }
 
        if (!strequal(driver->configfile, driver->driverpath) &&
                !strequal(driver->configfile, driver->datafile)) {
-       slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->configfile);       
-       slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->configfile);    
+               slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->configfile);       
+               slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->configfile);    
                if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
-               DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
-                       old_name, new_name ));
-               close_cnum(conn, user->vuid);
-               unbecome_root();
-               return False;
-       }
+                       DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
+                               old_name, new_name ));
+                       close_cnum(conn, user->vuid);
+                       pop_sec_ctx();
+                       return False;
+               }
        }
 
        if (!strequal(driver->helpfile, driver->driverpath) &&
-               !strequal(driver->helpfile, driver->datafile) &&
-               !strequal(driver->helpfile, driver->configfile)) {
-       slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->helpfile); 
-       slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->helpfile);      
+                       !strequal(driver->helpfile, driver->datafile) &&
+                       !strequal(driver->helpfile, driver->configfile)) {
+               slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->helpfile); 
+               slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->helpfile);      
                if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
-               DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
-                       old_name, new_name ));
-               close_cnum(conn, user->vuid);
-               unbecome_root();
-               return False;
-       }
+                       DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
+                               old_name, new_name ));
+                       close_cnum(conn, user->vuid);
+                       pop_sec_ctx();
+                       return False;
+               }
        }
 
        if (driver->dependentfiles) {
                for (i=0; *driver->dependentfiles[i]; i++) {
                        if (!strequal(driver->dependentfiles[i], driver->driverpath) &&
-                               !strequal(driver->dependentfiles[i], driver->datafile) &&
-                               !strequal(driver->dependentfiles[i], driver->configfile) &&
-                               !strequal(driver->dependentfiles[i], driver->helpfile)) {
-                       slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->dependentfiles[i]);        
-                       slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->dependentfiles[i]);     
+                                       !strequal(driver->dependentfiles[i], driver->datafile) &&
+                                       !strequal(driver->dependentfiles[i], driver->configfile) &&
+                                       !strequal(driver->dependentfiles[i], driver->helpfile)) {
+                               slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->dependentfiles[i]);        
+                               slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->dependentfiles[i]);     
                                if ((outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, True)) != 0) {
                                        DEBUG(0,("move_driver_to_download_area: Unable to rename %s to %s\n",
                                                old_name, new_name ));
                                        close_cnum(conn, user->vuid);
-                                       unbecome_root();
+                                       pop_sec_ctx();
                                        return False;
                                }
                        }
@@ -524,7 +530,7 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
        }
 
        close_cnum(conn, user->vuid);
-       unbecome_root();
+       pop_sec_ctx();
 
        return True;
 }
@@ -1946,7 +1952,7 @@ uint32 nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
 
 static SEC_DESC_BUF *construct_default_printer_sdb(void)
 {
-       SEC_ACE ace;
+       SEC_ACE ace[2];
        SEC_ACCESS sa;
        SEC_ACL *psa = NULL;
        SEC_DESC_BUF *sdb = NULL;
@@ -1958,7 +1964,7 @@ static SEC_DESC_BUF *construct_default_printer_sdb(void)
        /* Create an ACE where Everyone is allowed to print */
 
        init_sec_access(&sa, PRINTER_ACE_PRINT);
-       init_sec_ace(&ace, &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
+       init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
                     sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
 
 
@@ -1969,13 +1975,22 @@ static SEC_DESC_BUF *construct_default_printer_sdb(void)
                sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
        } else {
 
-               /* Backup plan - make printer owned by world.  This should
+               /* Backup plan - make printer owned by admins or root.  This should
                   emulate a lanman printer as security settings can't be
                   changed. */
 
-               sid_copy(&owner_sid, &global_sid_World);
+               if (!lookup_name( "Printer Administrators", &owner_sid, &name_type) &&
+                       !lookup_name( "Administrators", &owner_sid, &name_type) &&
+                       !lookup_name( "Administrator", &owner_sid, &name_type) &&
+                       !lookup_name("root", &owner_sid, &name_type)) {
+                                               sid_copy(&owner_sid, &global_sid_World);
+               }
        }
 
+       init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
+       init_sec_ace(&ace[1], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
+                    sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
+
        /* The ACL revision number in rpc_secdesc.h differs from the one
           created by NT when setting ACE entries in printer
           descriptors.  NT4 complains about the property being edited by a
@@ -1983,7 +1998,7 @@ static SEC_DESC_BUF *construct_default_printer_sdb(void)
 
 #define NT4_ACL_REVISION 0x2
 
-       if ((psa = make_sec_acl(NT4_ACL_REVISION, 1, &ace)) != NULL) {
+       if ((psa = make_sec_acl(NT4_ACL_REVISION, 2, ace)) != NULL) {
                psd = make_sec_desc(SEC_DESC_REVISION, 
                                    SEC_DESC_SELF_RELATIVE | 
                                    SEC_DESC_DACL_PRESENT,
index 118c2f46b6cb0a69620a526c850741adc28951c1..f185ffcdaa3f480ca942b2fb41bc2ae15fec7f1a 100644 (file)
@@ -221,15 +221,17 @@ BOOL push_sec_ctx(void)
 
        /* Check we don't overflow our stack */
 
-       if (sec_ctx_stack_ndx == (MAX_SEC_CTX_DEPTH)) {
+       if (sec_ctx_stack_ndx == MAX_SEC_CTX_DEPTH) {
                DEBUG(0, ("Security context stack overflow!\n"));
-               return False;
+               smb_panic("Security context stack overflow!\n");
        }
 
        /* Store previous user context */
 
        sec_ctx_stack_ndx++;
 
+       DEBUG(3, ("push_sec_ctx() : sec_ctx_stack_ndx = %d\n", sec_ctx_stack_ndx ));
+
        ctx_p = &sec_ctx_stack[sec_ctx_stack_ndx];
 
        ctx_p->uid = geteuid();
@@ -264,7 +266,7 @@ void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, NT_USER_TOKEN
 
        /* Set the security context */
 
-       DEBUG(3, ("setting sec ctx (%d, %d)\n", uid, gid));
+       DEBUG(3, ("setting sec ctx (%d, %d) - sec_ctx_stack_ndx = %d\n", uid, gid, sec_ctx_stack_ndx));
 
        gain_root();
 
@@ -275,6 +277,11 @@ void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, NT_USER_TOKEN
        ctx_p->ngroups = ngroups;
 
        safe_free(ctx_p->groups);
+#if 1 /* JRATEST */
+       if (token && (token == ctx_p->token))
+               smb_panic("DUPLICATE_TOKEN");
+#endif
+
        delete_nt_token(&ctx_p->token);
        
        ctx_p->groups = memdup(groups, sizeof(gid_t) * ngroups);
@@ -318,7 +325,7 @@ BOOL pop_sec_ctx(void)
 
        if (sec_ctx_stack_ndx == 0) {
                DEBUG(0, ("Security context stack underflow!\n"));
-               return False;
+               smb_panic("Security context stack underflow!\n");
        }
 
        ctx_p = &sec_ctx_stack[sec_ctx_stack_ndx];
@@ -355,7 +362,7 @@ BOOL pop_sec_ctx(void)
        current_user.groups = prev_ctx_p->groups;
        current_user.nt_user_token = prev_ctx_p->token;
 
-       DEBUG(3, ("popped off to sec ctx (%d, %d)\n", geteuid(), getegid()));
+       DEBUG(3, ("pop_sec_ctx (%d, %d) - sec_ctx_stack_ndx = %d\n", geteuid(), getegid(), sec_ctx_stack_ndx));
 
        return True;
 }
index fafcd71b1a3429f748344d25313f9e079c60212f..b28f056a3015f048820515f863d96748127bc878 100644 (file)
@@ -89,6 +89,8 @@ BOOL become_user(connection_struct *conn, uint16 vuid)
        gid_t gid;
        uid_t uid;
        char group_c;
+       BOOL must_free_token = False;
+       NT_USER_TOKEN *token = NULL;
 
        if (!conn) {
                DEBUG(2,("Connection not open\n"));
@@ -125,6 +127,7 @@ BOOL become_user(connection_struct *conn, uint16 vuid)
                gid = conn->gid;
                current_user.groups = conn->groups;
                current_user.ngroups = conn->ngroups;
+               token = conn->nt_user_token;
        } else {
                if (!vuser) {
                        DEBUG(2,("Invalid vuid used %d\n",vuid));
@@ -134,6 +137,7 @@ BOOL become_user(connection_struct *conn, uint16 vuid)
                gid = vuser->gid;
                current_user.ngroups = vuser->n_groups;
                current_user.groups  = vuser->groups;
+               token = vuser->nt_user_token;
        }
 
        /*
@@ -162,13 +166,27 @@ BOOL become_user(connection_struct *conn, uint16 vuid)
                } else {
                        gid = conn->gid;
                }
+
+               /*
+                * We've changed the group list in the token - we must
+                * re-create it.
+                */
+
+               token = create_nt_token(uid, gid, current_user.ngroups, current_user.groups);
+               must_free_token = True;
        }
        
-       set_sec_ctx(uid, gid, current_user.ngroups, current_user.groups, current_user.nt_user_token);
+       set_sec_ctx(uid, gid, current_user.ngroups, current_user.groups, token);
+
+       /*
+        * Free the new token (as set_sec_ctx copies it).
+        */
+
+       if (must_free_token)
+               delete_nt_token(&token);
 
        current_user.conn = conn;
        current_user.vuid = vuid;
-       current_user.nt_user_token = conn->nt_user_token;
 
        DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d)\n",
                 (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));