diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/lib/util_seaccess.c | 17 | ||||
-rw-r--r-- | source3/printing/nt_printing.c | 97 | ||||
-rw-r--r-- | source3/smbd/sec_ctx.c | 17 | ||||
-rw-r--r-- | source3/smbd/uid.c | 22 |
4 files changed, 103 insertions, 50 deletions
diff --git a/source3/lib/util_seaccess.c b/source3/lib/util_seaccess.c index 351e93dc7a..354f7f2fae 100644 --- a/source3/lib/util_seaccess.c +++ b/source3/lib/util_seaccess.c @@ -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; } diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 11c8e80276..c88217cc7e 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -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, diff --git a/source3/smbd/sec_ctx.c b/source3/smbd/sec_ctx.c index 118c2f46b6..f185ffcdaa 100644 --- a/source3/smbd/sec_ctx.c +++ b/source3/smbd/sec_ctx.c @@ -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; } diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index fafcd71b1a..b28f056a30 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -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())); |