diff options
author | Gerald Carter <jerry@samba.org> | 2005-04-11 21:40:01 +0000 |
---|---|---|
committer | Gerald Carter <jerry@samba.org> | 2005-04-11 21:40:01 +0000 |
commit | dae1a1db3c946093333d9e5001e30f75140fd3ca (patch) | |
tree | 77a0b497d3495c153ec0f7b6ec162c6d57314812 | |
parent | e1d96ed97614ef847df6038044143666a02c195f (diff) | |
download | samba-dae1a1db3c946093333d9e5001e30f75140fd3ca.tar.gz samba-dae1a1db3c946093333d9e5001e30f75140fd3ca.tar.xz samba-dae1a1db3c946093333d9e5001e30f75140fd3ca.zip |
r6299: last commits for 3.0.14samba-3.0.14
-rw-r--r-- | WHATSNEW.txt | 12 | ||||
-rw-r--r-- | source/lib/account_pol.c | 4 | ||||
-rw-r--r-- | source/nsswitch/winbindd_cm.c | 10 | ||||
-rw-r--r-- | source/param/loadparm.c | 2 | ||||
-rw-r--r-- | source/smbd/dosmode.c | 21 | ||||
-rw-r--r-- | source/smbd/posix_acls.c | 148 |
6 files changed, 147 insertions, 50 deletions
diff --git a/WHATSNEW.txt b/WHATSNEW.txt index f304eab4d22..e02cb1e8fab 100644 --- a/WHATSNEW.txt +++ b/WHATSNEW.txt @@ -24,6 +24,16 @@ Changes Changes since 3.0.13 -------------------- +smb.conf changes +---------------- + + Parameter Name Action + -------------- ------ + dos filetimes Enabled by default + + +commits +------- o Jeremy Allison <jra@samba.org> * Prevent nt_status code support when negotiating protocols earlier than NT1. @@ -35,6 +45,8 @@ o Jeremy Allison <jra@samba.org> FindNext(). * BUG 2581 (partial): Ensure if realloc fails on an internal tdb we fail gracefully. + * Ensure that 'dos filetimes' works with ACLs. + * Set 'dos filefimes = yes' as the default for smb.conf. o Gerald (Jerry) Carter <jerry@samba.org> diff --git a/source/lib/account_pol.c b/source/lib/account_pol.c index 5997d9180ae..72d6e77ddda 100644 --- a/source/lib/account_pol.c +++ b/source/lib/account_pol.c @@ -118,8 +118,8 @@ static const struct { {AP_MIN_PASSWORD_LEN, "min password length"}, {AP_PASSWORD_HISTORY, "password history"}, {AP_USER_MUST_LOGON_TO_CHG_PASS, "user must logon to change password"}, - {AP_MAX_PASSWORD_AGE, "maximum password age (seconds since 1970)"}, - {AP_MIN_PASSWORD_AGE,"minimum password age (seconds since 1970)"}, + {AP_MAX_PASSWORD_AGE, "maximum password age"}, + {AP_MIN_PASSWORD_AGE,"minimum password age"}, {AP_LOCK_ACCOUNT_DURATION, "lockout duration"}, {AP_RESET_COUNT_TIME, "reset count minutes"}, {AP_BAD_ATTEMPT_LOCKOUT, "bad lockout attempt"}, diff --git a/source/nsswitch/winbindd_cm.c b/source/nsswitch/winbindd_cm.c index 832672e64cb..c5cf1d5f464 100644 --- a/source/nsswitch/winbindd_cm.c +++ b/source/nsswitch/winbindd_cm.c @@ -1021,6 +1021,16 @@ NTSTATUS cm_get_sam_handle(struct winbindd_domain *domain, CLI_POLICY_HND **retu cli_shutdown(conn->cli); DLIST_REMOVE(cm_conns, conn); SAFE_FREE(conn); + + /* log a message for possible Windows 2003 SP1 DC's */ + if ( NT_STATUS_EQUAL(result,NT_STATUS_ACCESS_DENIED) && (lp_security() == SEC_DOMAIN) ) { + DEBUG(0,("samr_connect() received NT_STATUS_ACCESS_DENIED. If you are connecting \n")); + DEBUGADD(0,("to a Windows 2003 SP1 DC, this is a known issue. There are two current \n")); + DEBUGADD(0,("workarounds:\n")); + DEBUGADD(0,("(a) Move your configuration to security = ads, or\n")); + DEBUGADD(0,("(b) set 'client schannel = no' in smb.conf and use 'wbinfo --set-auth-user'\n")); + DEBUGADD(0,(" to define the credentials when connecting to the DC\n")); + } return result; } diff --git a/source/param/loadparm.c b/source/param/loadparm.c index d86f4b391a2..493f1142daa 100644 --- a/source/param/loadparm.c +++ b/source/param/loadparm.c @@ -533,7 +533,7 @@ static service sDefault = { False, /* bFakeOplocks */ False, /* bDeleteVetoFiles */ False, /* bDosFilemode */ - False, /* bDosFiletimes */ + True, /* bDosFiletimes */ False, /* bDosFiletimeResolution */ False, /* bFakeDirCreateTimes */ True, /* bBlockingLocks */ diff --git a/source/smbd/dosmode.c b/source/smbd/dosmode.c index fefcaca09d5..ff00b5dc6b1 100644 --- a/source/smbd/dosmode.c +++ b/source/smbd/dosmode.c @@ -433,8 +433,6 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode, int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) { - extern struct current_user current_user; - SMB_STRUCT_STAT sb; int ret = -1; errno = 0; @@ -454,21 +452,12 @@ int file_utime(connection_struct *conn, char *fname, struct utimbuf *times) (as DOS does). */ - if(SMB_VFS_STAT(conn,fname,&sb) != 0) - return -1; - /* Check if we have write access. */ - if (CAN_WRITE(conn)) { - if (((sb.st_mode & S_IWOTH) || conn->admin_user || - ((sb.st_mode & S_IWUSR) && current_user.uid==sb.st_uid) || - ((sb.st_mode & S_IWGRP) && - in_group(sb.st_gid,current_user.gid, - current_user.ngroups,current_user.groups)))) { - /* We are allowed to become root and change the filetime. */ - become_root(); - ret = SMB_VFS_UTIME(conn,fname, times); - unbecome_root(); - } + if (can_write_to_file(conn, fname)) { + /* We are allowed to become root and change the filetime. */ + become_root(); + ret = SMB_VFS_UTIME(conn,fname, times); + unbecome_root(); } return ret; diff --git a/source/smbd/posix_acls.c b/source/smbd/posix_acls.c index c5fa035c69c..52ddf4cad6d 100644 --- a/source/smbd/posix_acls.c +++ b/source/smbd/posix_acls.c @@ -3758,23 +3758,27 @@ BOOL set_unix_posix_acl(connection_struct *conn, files_struct *fsp, const char * Check for POSIX group ACLs. If none use stat entry. ****************************************************************************/ -static int check_posix_acl_group_write(connection_struct *conn, const char *dname, SMB_STRUCT_STAT *psbuf) +static int check_posix_acl_group_write(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf) { extern struct current_user current_user; SMB_ACL_T posix_acl = NULL; int entry_id = SMB_ACL_FIRST_ENTRY; SMB_ACL_ENTRY_T entry; int i; + BOOL seen_mask = False; int ret = -1; - if ((posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, dname, SMB_ACL_TYPE_ACCESS)) == NULL) { + if ((posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS)) == NULL) { goto check_stat; } /* First ensure the group mask allows group read. */ + /* Also check any user entries (these take preference over group). */ + while ( SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1) { SMB_ACL_TAG_T tagtype; SMB_ACL_PERMSET_T permset; + int have_write = -1; /* get_next... */ if (entry_id == SMB_ACL_FIRST_ENTRY) @@ -3788,20 +3792,51 @@ static int check_posix_acl_group_write(connection_struct *conn, const char *dnam goto check_stat; } + have_write = SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_WRITE); + if (have_write == -1) { + goto check_stat; + } + switch(tagtype) { case SMB_ACL_MASK: - if (!SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_WRITE)) { - /* We don't have group write permission. */ + if (!have_write) { + /* We don't have any group or explicit user write permission. */ ret = -1; /* Allow caller to check "other" permissions. */ + DEBUG(10,("check_posix_acl_group_write: file %s \ +refusing write due to mask.\n", fname)); goto done; } + seen_mask = True; break; + case SMB_ACL_USER: + { + /* Check against current_user.uid. */ + uid_t *puid = (uid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry); + if (puid == NULL) { + goto check_stat; + } + if (current_user.uid == *puid) { + /* We have a uid match but we must ensure we have seen the acl mask. */ + ret = have_write; + DEBUG(10,("check_posix_acl_group_write: file %s \ +match on user %u -> %s.\n", fname, (unsigned int)*puid, ret ? "can write" : "cannot write")); + if (seen_mask) { + goto done; + } + } + break; + } default: continue; } } - /* Now check all group entries. */ + /* If ret is anything other than -1 we matched on a user entry. */ + if (ret != -1) { + goto done; + } + + /* Next check all group entries. */ entry_id = SMB_ACL_FIRST_ENTRY; while ( SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1) { SMB_ACL_TAG_T tagtype; @@ -3826,50 +3861,54 @@ static int check_posix_acl_group_write(connection_struct *conn, const char *dnam } switch(tagtype) { - case SMB_ACL_USER: - { - /* Check against current_user.uid. */ - uid_t *puid = (uid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry); - if (puid == NULL) { - goto check_stat; - } - if (current_user.uid == *puid) { - /* We're done now we have a uid match. */ - ret = have_write; - goto done; - } - } - break; case SMB_ACL_GROUP: - { - gid_t *pgid = (gid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry); - if (pgid == NULL) { - goto check_stat; - } - for (i = 0; i < current_user.ngroups; i++) { - if (current_user.groups[i] == *pgid) { - /* We're done now we have a gid match. */ - ret = have_write; + { + gid_t *pgid = (gid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry); + if (pgid == NULL) { + goto check_stat; + } + for (i = 0; i < current_user.ngroups; i++) { + if (current_user.groups[i] == *pgid) { + ret = have_write; + DEBUG(10,("check_posix_acl_group_write: file %s \ +match on group %u -> can write.\n", fname, (unsigned int)*pgid )); + + /* If we don't have write permission this entry doesn't + terminate the enumeration of the entries. */ + if (have_write) { goto done; } + /* But does terminate the group iteration. */ + break; } } break; + } default: continue; } } + /* If we get here we know ret == 0. */ + SMB_ASSERT(ret == 0); check_stat: for (i = 0; i < current_user.ngroups; i++) { if (current_user.groups[i] == psbuf->st_gid) { ret = (psbuf->st_mode & S_IWGRP) ? 1 : 0; + DEBUG(10,("check_posix_acl_group_write: file %s \ +match on owning group %u -> %s.\n", fname, (unsigned int)psbuf->st_gid, ret ? "can write" : "cannot write")); break; } } + if (i == current_user.ngroups) { + SMB_ASSERT(ret != 1); + DEBUG(10,("check_posix_acl_group_write: file %s \ +failed to match on user or group in token.\n", fname )); + } + done: SMB_VFS_SYS_ACL_FREE_ACL(conn, posix_acl); @@ -3877,7 +3916,7 @@ static int check_posix_acl_group_write(connection_struct *conn, const char *dnam } /**************************************************************************** - Actually emulate the in-kernel access checking for write access. We need + Actually emulate the in-kernel access checking for delete access. We need this to successfully return ACCESS_DENIED on a file open for delete access. ****************************************************************************/ @@ -3888,6 +3927,11 @@ BOOL can_delete_file_in_directory(connection_struct *conn, const char *fname) pstring dname; int ret; + if (!CAN_WRITE(conn)) { + return False; + } + + /* Get the parent directory permission mask and owners. */ pstrcpy(dname, parent_dirname(fname)); if(SMB_VFS_STAT(conn, dname, &sbuf) != 0) { return False; @@ -3895,11 +3939,12 @@ BOOL can_delete_file_in_directory(connection_struct *conn, const char *fname) if (!S_ISDIR(sbuf.st_mode)) { return False; } - if (current_user.uid == 0) { + if (current_user.uid == 0 || conn->admin_user) { /* I'm sorry sir, I didn't know you were root... */ return True; } + /* Check primary owner write access. */ if (current_user.uid == sbuf.st_uid) { return (sbuf.st_mode & S_IWUSR) ? True : False; } @@ -3918,11 +3963,52 @@ BOOL can_delete_file_in_directory(connection_struct *conn, const char *fname) } #endif - /* Check group ownership. */ + /* Check group or explicit user acl entry write access. */ ret = check_posix_acl_group_write(conn, dname, &sbuf); if (ret == 0 || ret == 1) { return ret ? True : False; } + /* Finally check other write access. */ + return (sbuf.st_mode & S_IWOTH) ? True : False; +} + +/**************************************************************************** + Actually emulate the in-kernel access checking for write access. We need + this to successfully check for ability to write for dos filetimes. +****************************************************************************/ + +BOOL can_write_to_file(connection_struct *conn, const char *fname) +{ + extern struct current_user current_user; + SMB_STRUCT_STAT sbuf; + int ret; + + if (!CAN_WRITE(conn)) { + return False; + } + + if (current_user.uid == 0 || conn->admin_user) { + /* I'm sorry sir, I didn't know you were root... */ + return True; + } + + /* Get the file permission mask and owners. */ + if(SMB_VFS_STAT(conn, fname, &sbuf) != 0) { + return False; + } + + /* Check primary owner write access. */ + if (current_user.uid == sbuf.st_uid) { + return (sbuf.st_mode & S_IWUSR) ? True : False; + } + + /* Check group or explicit user acl entry write access. */ + ret = check_posix_acl_group_write(conn, fname, &sbuf); + if (ret == 0 || ret == 1) { + return ret ? True : False; + } + + /* Finally check other write access. */ return (sbuf.st_mode & S_IWOTH) ? True : False; } |