The branch, master has been updated via f9d19c4 Ensure gpfs kernel leases are wrapped in a become_root()/unbecome_root() pair. via 1af8b07 Wrap setting leases in become_root()/unbecome_root() to ensure correct delivery of signals. via 63db069 torture: add LOCAL-sid_to_string testcase via 1a21bc0 torture: add more string_to_sid torture testcases via edd3302 libcli: fix conversion logic in dom_sid_string_buf via 34d3639 libcli: fix conversion logic in dom_sid_parse_endp via ba9d861 wbclient: fix conversion logic in wbcSidToStringBuf via 1a4ec0b wbclient: fix conversion logic in wbcStringToSid via afcc7be schannel: Fix an unused variable from 7615b25 samba-tool dbcheck: Correctly remove deleted DNs in dbcheck
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit f9d19c459f01d6e316a4a74a900c69424962eae0 Author: Ralph Wuerthner <ral...@de.ibm.com> Date: Wed Jul 31 16:33:48 2013 -0700 Ensure gpfs kernel leases are wrapped in a become_root()/unbecome_root() pair. Ensures correct lease owner for signal delivery. Signed-off-by: Ralph Wuerthner <ral...@de.ibm.com> Reviewed-by: Jeremy Allison <j...@samba.org> Reviewed-by: Simo Sorce <i...@samba.org> Autobuild-User(master): Jeremy Allison <j...@samba.org> Autobuild-Date(master): Thu Aug 1 03:57:11 CEST 2013 on sn-devel-104 commit 1af8b0792913d3f280b5da0802e04df063f9f59e Author: Jeremy Allison <j...@samba.org> Date: Wed Jul 31 16:32:20 2013 -0700 Wrap setting leases in become_root()/unbecome_root() to ensure correct delivery of signals. Remove workaround for Linux kernel bug https://bugzilla.kernel.org/show_bug.cgi?id=43336 as we don't need to set capabilities when we're already root. Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Simo Sorce <i...@samba.org> commit 63db0694c45b1ce59b9232f0690226fce39f9c28 Author: Jeff Layton <jlay...@samba.org> Date: Wed Jul 31 10:38:23 2013 -0400 torture: add LOCAL-sid_to_string testcase Signed-off-by: Jeff Layton <jlay...@redhat.com> Reviewed-by: Jeremy Allison <j...@samba.org> commit 1a21bc04830958a8058d7304921c836edd63586e Author: Jeff Layton <jlay...@samba.org> Date: Wed Jul 31 10:38:22 2013 -0400 torture: add more string_to_sid torture testcases Signed-off-by: Jeff Layton <jlay...@redhat.com> Reviewed-by: Jeremy Allison <j...@samba.org> commit edd3302ad46fd70a8e5472f32f41aa4d8305f4e5 Author: Jeff Layton <jlay...@samba.org> Date: Wed Jul 31 10:38:21 2013 -0400 libcli: fix conversion logic in dom_sid_string_buf Signed-off-by: Jeff Layton <jlay...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 34d3639305bed5fd202114044fc76e53980dfee4 Author: Jeff Layton <jlay...@samba.org> Date: Wed Jul 31 10:38:20 2013 -0400 libcli: fix conversion logic in dom_sid_parse_endp Signed-off-by: Jeff Layton <jlay...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit ba9d8612e3f66fa7c8c1999c26c658167124b18f Author: Jeff Layton <jlay...@samba.org> Date: Wed Jul 31 10:38:19 2013 -0400 wbclient: fix conversion logic in wbcSidToStringBuf Might as well fix it to handle large authority values properly. Also correct some of the formatting. Signed-off-by: Jeff Layton <jlay...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 1a4ec0b885f95b481d9df6461bd4a8e8fd175f53 Author: Jeff Layton <jlay...@samba.org> Date: Wed Jul 31 10:38:18 2013 -0400 wbclient: fix conversion logic in wbcStringToSid Signed-off-by: Jeff Layton <jlay...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit afcc7beea590f6d480fcfa2e9b2540abee96f549 Author: Volker Lendecke <v...@samba.org> Date: Wed Jul 31 21:58:25 2013 +0200 schannel: Fix an unused variable Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> ----------------------------------------------------------------------- Summary of changes: libcli/auth/schannel_state_tdb.c | 1 - libcli/security/dom_sid.c | 57 ++++++++++++++++++------------- nsswitch/libwbclient/wbc_sid.c | 70 ++++++++++++++++++++----------------- source3/modules/vfs_gpfs.c | 6 +++ source3/selftest/tests.py | 1 + source3/smbd/oplock_linux.c | 33 +++++++++++------- source3/torture/torture.c | 46 +++++++++++++++++++++++++ 7 files changed, 144 insertions(+), 70 deletions(-) Changeset truncated at 500 lines: diff --git a/libcli/auth/schannel_state_tdb.c b/libcli/auth/schannel_state_tdb.c index 8f9c1f0..8c893ee 100644 --- a/libcli/auth/schannel_state_tdb.c +++ b/libcli/auth/schannel_state_tdb.c @@ -284,7 +284,6 @@ NTSTATUS schannel_check_creds_state(TALLOC_CTX *mem_ctx, struct db_context *db_sc; struct netlogon_creds_CredentialState *creds; NTSTATUS status; - int ret; char *name_upper = NULL; char *keystr = NULL; struct db_record *record; diff --git a/libcli/security/dom_sid.c b/libcli/security/dom_sid.c index 16b7af9..90f5401 100644 --- a/libcli/security/dom_sid.c +++ b/libcli/security/dom_sid.c @@ -120,6 +120,7 @@ int dom_sid_compare_domain(const struct dom_sid *sid1, Convert a string to a SID. Returns True on success, False on fail. Return the first character not parsed in endp. *****************************************************************/ +#define AUTHORITY_MASK (~(0xffffffffffffULL)) bool dom_sid_parse_endp(const char *sidstr,struct dom_sid *sidout, const char **endp) @@ -127,7 +128,7 @@ bool dom_sid_parse_endp(const char *sidstr,struct dom_sid *sidout, const char *p; char *q; /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */ - uint32_t conv; + uint64_t conv; ZERO_STRUCTP(sidout); @@ -142,8 +143,8 @@ bool dom_sid_parse_endp(const char *sidstr,struct dom_sid *sidout, goto format_error; } - conv = (uint32_t) strtoul(p, &q, 10); - if (!q || (*q != '-')) { + conv = strtoul(p, &q, 10); + if (!q || (*q != '-') || conv > UINT8_MAX) { goto format_error; } sidout->sid_rev_num = (uint8_t) conv; @@ -154,19 +155,19 @@ bool dom_sid_parse_endp(const char *sidstr,struct dom_sid *sidout, } /* get identauth */ - conv = (uint32_t) strtoul(q, &q, 10); - if (!q) { + conv = strtoull(q, &q, 0); + if (!q || conv & AUTHORITY_MASK) { goto format_error; } - /* identauth in decimal should be < 2^32 */ + /* When identauth >= UINT32_MAX, it's in hex with a leading 0x */ /* NOTE - the conv value is in big-endian format. */ - sidout->id_auth[0] = 0; - sidout->id_auth[1] = 0; - sidout->id_auth[2] = (conv & 0xff000000) >> 24; - sidout->id_auth[3] = (conv & 0x00ff0000) >> 16; - sidout->id_auth[4] = (conv & 0x0000ff00) >> 8; - sidout->id_auth[5] = (conv & 0x000000ff); + sidout->id_auth[0] = (conv & 0xff0000000000ULL) >> 40; + sidout->id_auth[1] = (conv & 0x00ff00000000ULL) >> 32; + sidout->id_auth[2] = (conv & 0x0000ff000000ULL) >> 24; + sidout->id_auth[3] = (conv & 0x000000ff0000ULL) >> 16; + sidout->id_auth[4] = (conv & 0x00000000ff00ULL) >> 8; + sidout->id_auth[5] = (conv & 0x0000000000ffULL); sidout->num_auths = 0; if (*q != '-') { @@ -183,8 +184,8 @@ bool dom_sid_parse_endp(const char *sidstr,struct dom_sid *sidout, goto format_error; } - conv = strtoul(q, &end, 10); - if (end == q) { + conv = strtoull(q, &end, 10); + if (end == q || conv > UINT32_MAX) { goto format_error; } @@ -364,23 +365,31 @@ bool dom_sid_in_domain(const struct dom_sid *domain_sid, int dom_sid_string_buf(const struct dom_sid *sid, char *buf, int buflen) { int i, ofs; - uint32_t ia; + uint64_t ia; if (!sid) { return strlcpy(buf, "(NULL SID)", buflen); } - ia = (sid->id_auth[5]) + - (sid->id_auth[4] << 8 ) + - (sid->id_auth[3] << 16) + - (sid->id_auth[2] << 24); - - ofs = snprintf(buf, buflen, "S-%u-%lu", - (unsigned int)sid->sid_rev_num, (unsigned long)ia); + ia = ((uint64_t)sid->id_auth[5]) + + ((uint64_t)sid->id_auth[4] << 8 ) + + ((uint64_t)sid->id_auth[3] << 16) + + ((uint64_t)sid->id_auth[2] << 24) + + ((uint64_t)sid->id_auth[1] << 32) + + ((uint64_t)sid->id_auth[0] << 40); + + ofs = snprintf(buf, buflen, "S-%hhu-", (unsigned char)sid->sid_rev_num); + if (ia >= UINT32_MAX) { + ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "0x%llx", + (unsigned long long)ia); + } else { + ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "%llu", + (unsigned long long)ia); + } for (i = 0; i < sid->num_auths; i++) { - ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "-%lu", - (unsigned long)sid->sub_auths[i]); + ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "-%u", + (unsigned int)sid->sub_auths[i]); } return ofs; } diff --git a/nsswitch/libwbclient/wbc_sid.c b/nsswitch/libwbclient/wbc_sid.c index bab6933..471f71b 100644 --- a/nsswitch/libwbclient/wbc_sid.c +++ b/nsswitch/libwbclient/wbc_sid.c @@ -32,7 +32,7 @@ * result if it was long enough. */ int wbcSidToStringBuf(const struct wbcDomainSid *sid, char *buf, int buflen) { - uint32_t id_auth; + uint64_t id_auth; int i, ofs; if (!sid) { @@ -40,22 +40,25 @@ int wbcSidToStringBuf(const struct wbcDomainSid *sid, char *buf, int buflen) return 10; /* strlen("(NULL SID)") */ } - /* - * BIG NOTE: this function only does SIDS where the identauth is not - * >= ^32 in a range of 2^48. - */ - - id_auth = sid->id_auth[5] + - (sid->id_auth[4] << 8) + - (sid->id_auth[3] << 16) + - (sid->id_auth[2] << 24); + id_auth = (uint64_t)sid->id_auth[5] + + ((uint64_t)sid->id_auth[4] << 8) + + ((uint64_t)sid->id_auth[3] << 16) + + ((uint64_t)sid->id_auth[2] << 24) + + ((uint64_t)sid->id_auth[1] << 32) + + ((uint64_t)sid->id_auth[0] << 40); - ofs = snprintf(buf, buflen, "S-%u-%lu", - (unsigned int)sid->sid_rev_num, (unsigned long)id_auth); + ofs = snprintf(buf, buflen, "S-%hhu-", (unsigned char)sid->sid_rev_num); + if (id_auth >= UINT32_MAX) { + ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "0x%llx", + (unsigned long long)id_auth); + } else { + ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "%llu", + (unsigned long long)id_auth); + } for (i = 0; i < sid->num_auths; i++) { - ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "-%lu", - (unsigned long)sid->sub_auths[i]); + ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "-%u", + (unsigned int)sid->sub_auths[i]); } return ofs; } @@ -88,13 +91,15 @@ wbcErr wbcSidToString(const struct wbcDomainSid *sid, return WBC_ERR_SUCCESS; } +#define AUTHORITY_MASK (~(0xffffffffffffULL)) + /* Convert a character string to a binary SID */ wbcErr wbcStringToSid(const char *str, struct wbcDomainSid *sid) { const char *p; char *q; - uint32_t x; + uint64_t x; wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; if (!sid) { @@ -115,38 +120,39 @@ wbcErr wbcStringToSid(const char *str, /* Get the SID revision number */ p = str+2; - x = (uint32_t)strtol(p, &q, 10); - if (x==0 || !q || *q!='-') { + x = (uint64_t)strtoul(p, &q, 10); + if (x==0 || x > UINT8_MAX || !q || *q!='-') { wbc_status = WBC_ERR_INVALID_SID; BAIL_ON_WBC_ERROR(wbc_status); } sid->sid_rev_num = (uint8_t)x; - /* Next the Identifier Authority. This is stored in big-endian - in a 6 byte array. */ - + /* + * Next the Identifier Authority. This is stored big-endian in a + * 6 byte array. If the authority value is >= UINT_MAX, then it should + * be expressed as a hex value, according to MS-DTYP. + */ p = q+1; - x = (uint32_t)strtol(p, &q, 10); - if (!q || *q!='-') { + x = strtoull(p, &q, 0); + if (!q || *q!='-' || (x & AUTHORITY_MASK)) { wbc_status = WBC_ERR_INVALID_SID; BAIL_ON_WBC_ERROR(wbc_status); } - sid->id_auth[5] = (x & 0x000000ff); - sid->id_auth[4] = (x & 0x0000ff00) >> 8; - sid->id_auth[3] = (x & 0x00ff0000) >> 16; - sid->id_auth[2] = (x & 0xff000000) >> 24; - sid->id_auth[1] = 0; - sid->id_auth[0] = 0; + sid->id_auth[5] = (x & 0x0000000000ffULL); + sid->id_auth[4] = (x & 0x00000000ff00ULL) >> 8; + sid->id_auth[3] = (x & 0x000000ff0000ULL) >> 16; + sid->id_auth[2] = (x & 0x0000ff000000ULL) >> 24; + sid->id_auth[1] = (x & 0x00ff00000000ULL) >> 32; + sid->id_auth[0] = (x & 0xff0000000000ULL) >> 40; /* now read the the subauthorities */ - p = q +1; sid->num_auths = 0; while (sid->num_auths < WBC_MAXSUBAUTHS) { - x=(uint32_t)strtoul(p, &q, 10); + x = strtoull(p, &q, 10); if (p == q) break; - if (q == NULL) { + if (x > UINT32_MAX) { wbc_status = WBC_ERR_INVALID_SID; BAIL_ON_WBC_ERROR(wbc_status); } diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 13061c8..4a53bf8 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -111,7 +111,13 @@ static int vfs_gpfs_setlease(vfs_handle_struct *handle, files_struct *fsp, START_PROFILE(syscall_linux_setlease); if (config->leases) { + /* + * Ensure the lease owner is root to allow + * correct delivery of lease-break signals. + */ + become_root(); ret = set_gpfs_lease(fsp->fh->fd,leasetype); + unbecome_root(); } END_PROFILE(syscall_linux_setlease); diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index 3fc6684..afab687 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -99,6 +99,7 @@ local_tests = [ "LOCAL-STREAM-NAME", "LOCAL-WBCLIENT", "LOCAL-string_to_sid", + "LOCAL-sid_to_string", "LOCAL-binary_to_sid", "LOCAL-DBTRANS", "LOCAL-TEVENT-SELECT", diff --git a/source3/smbd/oplock_linux.c b/source3/smbd/oplock_linux.c index 7fa9b7c..dd772bf 100644 --- a/source3/smbd/oplock_linux.c +++ b/source3/smbd/oplock_linux.c @@ -75,26 +75,33 @@ int linux_set_lease_sighandler(int fd) int linux_setlease(int fd, int leasetype) { int ret; + int saved_errno; + + /* + * Ensure the lease owner is root to allow + * correct delivery of lease-break signals. + */ + + become_root(); /* First set the signal handler. */ if (linux_set_lease_sighandler(fd) == -1) { - return -1; + saved_errno = errno; + ret = -1; + goto out; } ret = fcntl(fd, F_SETLEASE, leasetype); - if (ret == -1 && errno == EACCES) { - set_effective_capability(LEASE_CAPABILITY); - /* - * Bug 8974 - work around Linux kernel bug - * https://bugzilla.kernel.org/show_bug.cgi?id=43336. - * "fcntl(F_SETLEASE) resets signal number when - * called multiple times" - */ - if (linux_set_lease_sighandler(fd) == -1) { - return -1; - } - ret = fcntl(fd, F_SETLEASE, leasetype); + if (ret == -1) { + saved_errno = errno; } + out: + + unbecome_root(); + + if (ret == -1) { + errno = saved_errno; + } return ret; } diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 3c6db30..b0b498f 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -8469,6 +8469,22 @@ static bool run_local_string_to_sid(int dummy) { printf("allowing S-1-5-32-545-abc\n"); return false; } + if (string_to_sid(&sid, "S-300-5-32-545")) { + printf("allowing S-300-5-32-545\n"); + return false; + } + if (string_to_sid(&sid, "S-1-0xfffffffffffffe-32-545")) { + printf("allowing S-1-0xfffffffffffffe-32-545\n"); + return false; + } + if (string_to_sid(&sid, "S-1-0xffffffffffff-5294967297-545")) { + printf("allowing S-1-0xffffffffffff-5294967297-545\n"); + return false; + } + if (!string_to_sid(&sid, "S-1-0xfffffffffffe-32-545")) { + printf("could not parse S-1-0xfffffffffffe-32-545\n"); + return false; + } if (!string_to_sid(&sid, "S-1-5-32-545")) { printf("could not parse S-1-5-32-545\n"); return false; @@ -8481,6 +8497,35 @@ static bool run_local_string_to_sid(int dummy) { return true; } +static bool sid_to_string_test(char *expected) { + char *str; + bool res = true; + struct dom_sid sid; + + if (!string_to_sid(&sid, expected)) { + printf("could not parse %s\n", expected); + return false; + } + + str = dom_sid_string(NULL, &sid); + if (strcmp(str, expected)) { + printf("Comparison failed (%s != %s)\n", str, expected); + res = false; + } + TALLOC_FREE(str); + return res; +} + +static bool run_local_sid_to_string(int dummy) { + if (!sid_to_string_test("S-1-0xffffffffffff-1-1-1-1-1-1-1-1-1-1-1-1")) + return false; + if (!sid_to_string_test("S-1-545")) + return false; + if (!sid_to_string_test("S-255-3840-1-1-1-1")) + return false; + return true; +} + static bool run_local_binary_to_sid(int dummy) { struct dom_sid *sid = talloc(NULL, struct dom_sid); static const char good_binary_sid[] = { @@ -9522,6 +9567,7 @@ static struct { { "LOCAL-STREAM-NAME", run_local_stream_name, 0}, { "LOCAL-WBCLIENT", run_local_wbclient, 0}, { "LOCAL-string_to_sid", run_local_string_to_sid, 0}, + { "LOCAL-sid_to_string", run_local_sid_to_string, 0}, { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0}, { "LOCAL-DBTRANS", run_local_dbtrans, 0}, { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0}, -- Samba Shared Repository