From c36031778e1983ddb11d3e1fcab35e738dbf94bc Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Tue, 26 May 2009 09:26:56 +0200 Subject: s3 WHATSNEW: Mention the changes to net --- WHATSNEW.txt | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/WHATSNEW.txt b/WHATSNEW.txt index 066f718999..fe8d541de8 100644 --- a/WHATSNEW.txt +++ b/WHATSNEW.txt @@ -14,6 +14,9 @@ Authentication Changes: o Changed the way smbd handles untrusted domain names given during user authentication +net Command Changes: +o parameter syntax made more consistent + Authentication Changes ====================== @@ -32,6 +35,38 @@ on smbd to always pass through bogus names to the DC for verification. A new parameter "map untrusted to domain" can be enabled to revert to the legacy behavior. +net Command Changes +=================== + +The net command now accepts the common command line parameters most other Samba +command line utilities use, with a couple of remaining differences: + +-l still gives long output for net commands supporting the --long flag. This was +more useful than the common --log-base parameter. + +-i still tells net to read data from stdin (like --stdin) instead of toggling +the common --scope flag. + +-S still tells net the server to connect to (like --server) instead of +negotiating the common --signing flag. As -S is probably used by most scripts +doing net rpc commands, this would have been a high-impact change for little +gain. + +This change was mainly done to unify the authentification options. Here, one +flag changed it's meaning and one useful flag was added. + +-N used to be the short version of --ntname. It now matches the Samba default of +--no-pass. Use this to stop net from prompting for a password if you want +anonymous authentication. + +-A --authentication-file now takes an authentication file with the username and +password you want net to use, avoiding a password prompt as with plain -U user +or having to give a password on the command line as in -U user%pass. + +Last but not least net now always falls back to your local unix username if no +-U is specified and a username is needed. net rpc commands will now prompt for a +password unless one is specified using either -U user%pass or -A auth_file. + ###################################################################### Reporting bugs & Development Discussion ####################################### -- cgit From d0051462b99ab3102cebe5ce17bf517b5bdf6c03 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 22 May 2009 22:23:42 +0200 Subject: s4:libcli/smb2: add some more SMB2 constants metze --- source4/libcli/smb2/smb2_constants.h | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/source4/libcli/smb2/smb2_constants.h b/source4/libcli/smb2/smb2_constants.h index 86dfbfedbe..1a69d54e53 100644 --- a/source4/libcli/smb2/smb2_constants.h +++ b/source4/libcli/smb2/smb2_constants.h @@ -68,10 +68,15 @@ #define SMB2_MAGIC 0x424D53FE /* 0xFE 'S' 'M' 'B' */ -/* the dialects we support */ -#define SMB2_DIALECT_REVISION 0x202 -#define SMB21_DIALECT_REVISION 0x210 -#define SMB2_LONGHORN_BETA_DIALECT_REVISION 0x0 /* early beta dialect */ +/* SMB2 negotiate dialects */ +#define SMB2_DIALECT_REVISION_000 0x0000 /* early beta dialect */ +#define SMB2_DIALECT_REVISION_202 0x0202 +#define SMB2_DIALECT_REVISION_210 0x0210 +#define SMB2_DIALECT_REVISION_2FF 0x02FF + +#define SMB2_DIALECT_REVISION SMB2_DIALECT_REVISION_202 +#define SMB21_DIALECT_REVISION SMB2_DIALECT_REVISION_210 +#define SMB2_LONGHORN_BETA_DIALECT_REVISION SMB2_DIALECT_REVISION_000 /* SMB2 negotiate security_mode */ #define SMB2_NEGOTIATE_SIGNING_ENABLED 0x01 @@ -79,9 +84,14 @@ /* SMB2 capabilities - only 1 so far. I'm sure more will be added */ #define SMB2_CAP_DFS 0x00000001 +#define SMB2_CAP_LEASING 0x00000002 /* only in dialect 0x210 */ /* so we can spot new caps as added */ #define SMB2_CAP_ALL SMB2_CAP_DFS +/* SMB2 session flags */ +#define SMB2_SESSION_FLAG_IS_GUEST 0x0001 +#define SMB2_SESSION_FLAG_IS_NULL 0x0002 + /* SMB2 share flags */ #define SMB2_SHAREFLAG_MANUAL_CACHING 0x0000 #define SMB2_SHAREFLAG_AUTO_CACHING 0x0010 -- cgit From 01b05df766cf55c356af495151ac665a82a57c4b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 26 May 2009 09:38:09 +0200 Subject: s4:libcli/smb2: use new SMB2_DIVELECT_REVISION constants Also send them in the order a windows client would send them (the lowest first). metze --- source4/libcli/smb2/connect.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index 8d6ea04dc8..8c1a73b681 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -164,8 +164,11 @@ static void continue_socket(struct composite_context *creq) struct smbcli_socket *sock; struct smb2_transport *transport; struct smb2_request *req; - uint16_t dialects[3] = { SMB2_DIALECT_REVISION, SMB21_DIALECT_REVISION, - SMB2_LONGHORN_BETA_DIALECT_REVISION }; + uint16_t dialects[3] = { + SMB2_DIALECT_REVISION_000, + SMB2_DIALECT_REVISION_202, + SMB2_DIALECT_REVISION_210 + }; c->status = smbcli_sock_connect_recv(creq, state, &sock); if (!composite_is_ok(c)) return; -- cgit From fadffbae88335a45f23d4861c6a097bccb191069 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 26 May 2009 08:44:27 +0200 Subject: s4:smb2srv: We only support SMB 2.002. We need to loop over all given dialects and check if we can find SMB2_DIALECT_REVISION_202. metze --- source4/smb_server/smb/negprot.c | 1 - source4/smb_server/smb2/negprot.c | 17 ++++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/source4/smb_server/smb/negprot.c b/source4/smb_server/smb/negprot.c index c3399fdd48..5ac5624745 100644 --- a/source4/smb_server/smb/negprot.c +++ b/source4/smb_server/smb/negprot.c @@ -469,7 +469,6 @@ static const struct { int protocol_level; } supported_protocols[] = { {"SMB 2.002", "SMB2", reply_smb2, PROTOCOL_SMB2}, - {"SMB 2.001", "SMB2", reply_smb2, PROTOCOL_SMB2}, {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1}, {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1}, {"LANMAN2.1", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2}, diff --git a/source4/smb_server/smb2/negprot.c b/source4/smb_server/smb2/negprot.c index 0b65a19634..f915392ffa 100644 --- a/source4/smb_server/smb2/negprot.c +++ b/source4/smb_server/smb2/negprot.c @@ -97,14 +97,21 @@ static NTSTATUS smb2srv_negprot_backend(struct smb2srv_request *req, struct smb2 NTSTATUS status; struct timeval current_time; struct timeval boot_time; + uint16_t i; + uint16_t dialect = 0; /* we only do one dialect for now */ if (io->in.dialect_count < 1) { return NT_STATUS_NOT_SUPPORTED; } - if (io->in.dialects[0] != 0 && - io->in.dialects[0] != SMB2_DIALECT_REVISION) { - DEBUG(0,("Got unexpected SMB2 dialect %u\n", io->in.dialects[0])); + for (i=0; i < io->in.dialect_count; i++) { + dialect = io->in.dialects[i]; + if (dialect == SMB2_DIALECT_REVISION_202) { + break; + } + } + if (dialect != SMB2_DIALECT_REVISION_202) { + DEBUG(0,("Got unexpected SMB2 dialect %u\n", dialect)); return NT_STATUS_NOT_SUPPORTED; } @@ -128,7 +135,7 @@ static NTSTATUS smb2srv_negprot_backend(struct smb2srv_request *req, struct smb2 req->smb_conn->smb2_signing_required = true; break; } - io->out.dialect_revision = SMB2_DIALECT_REVISION; + io->out.dialect_revision = dialect; io->out.capabilities = 0; io->out.max_transact_size = lp_parm_ulong(req->smb_conn->lp_ctx, NULL, "smb2", "max transaction size", 0x10000); @@ -281,7 +288,7 @@ void smb2srv_reply_smb_negprot(struct smbsrv_request *smb_req) SSVAL(req->in.body, 0x02, 1); memset(req->in.body+0x04, 0, 32); - SSVAL(req->in.body, 0x24, 0); + SSVAL(req->in.body, 0x24, SMB2_DIALECT_REVISION_202); smb2srv_negprot_recv(req); return; -- cgit From 53df34364416d3ce037024147788fdc968bdb31f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 26 May 2009 09:37:29 +0200 Subject: s4:libcli/smb2: remove old dialect revision constants metze --- source4/libcli/smb2/smb2_constants.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/source4/libcli/smb2/smb2_constants.h b/source4/libcli/smb2/smb2_constants.h index 1a69d54e53..48f30972dc 100644 --- a/source4/libcli/smb2/smb2_constants.h +++ b/source4/libcli/smb2/smb2_constants.h @@ -74,10 +74,6 @@ #define SMB2_DIALECT_REVISION_210 0x0210 #define SMB2_DIALECT_REVISION_2FF 0x02FF -#define SMB2_DIALECT_REVISION SMB2_DIALECT_REVISION_202 -#define SMB21_DIALECT_REVISION SMB2_DIALECT_REVISION_210 -#define SMB2_LONGHORN_BETA_DIALECT_REVISION SMB2_DIALECT_REVISION_000 - /* SMB2 negotiate security_mode */ #define SMB2_NEGOTIATE_SIGNING_ENABLED 0x01 #define SMB2_NEGOTIATE_SIGNING_REQUIRED 0x02 -- cgit From bd8a38b60e933bcffd90ea8bed75898a421cbdad Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 22 May 2009 21:26:03 +0200 Subject: s3:smbd: return the correct security mode and capabilities in SMB2 Negotitate metze --- source3/smbd/smb2_negprot.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/source3/smbd/smb2_negprot.c b/source3/smbd/smb2_negprot.c index b976ea2399..e9464900f2 100644 --- a/source3/smbd/smb2_negprot.c +++ b/source3/smbd/smb2_negprot.c @@ -74,8 +74,10 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req) size_t body_size; size_t expected_dyn_size = 0; size_t c; + uint16_t security_mode; uint16_t dialect_count; uint16_t dialect; + uint32_t capabilities; /* TODO: drop the connection with INVALI_PARAMETER */ @@ -103,12 +105,12 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req) for (c=0; c < dialect_count; c++) { dialect = SVAL(indyn, c*2); - if (dialect == 0x0202) { + if (dialect == SMB2_DIALECT_REVISION_202) { break; } } - if (dialect != 0x0202) { + if (dialect != SMB2_DIALECT_REVISION_202) { return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); } @@ -129,6 +131,16 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req) return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR); } + security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED; + if (lp_server_signing() == Required) { + security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED; + } + + capabilities = 0; + if (lp_host_msdfs()) { + capabilities |= SMB2_CAP_DFS; + } + security_offset = SMB2_HDR_BODY + 0x40; security_buffer = data_blob_const(negprot_spnego_blob.data + 16, negprot_spnego_blob.length - 16); @@ -142,13 +154,14 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req) } SSVAL(outbody.data, 0x00, 0x40 + 1); /* struct size */ -/*TODO: indicate signing enabled */ - SSVAL(outbody.data, 0x02, 0); /* security mode */ + SSVAL(outbody.data, 0x02, + security_mode); /* security mode */ SSVAL(outbody.data, 0x04, dialect); /* dialect revision */ SSVAL(outbody.data, 0x06, 0); /* reserved */ memcpy(outbody.data + 0x08, negprot_spnego_blob.data, 16); /* server guid */ - SIVAL(outbody.data, 0x18, 0); /* capabilities */ + SIVAL(outbody.data, 0x18, + capabilities); /* capabilities */ SIVAL(outbody.data, 0x1C, 0x00010000); /* max transact size */ SIVAL(outbody.data, 0x20, 0x00010000); /* max read size */ SIVAL(outbody.data, 0x24, 0x00010000); /* max write size */ -- cgit From 31c6679bf12bbcd6626bfd5066bb2e751314e9c2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 22 May 2009 22:58:39 +0200 Subject: s3:smbd: add support for SMB2 signing metze --- source3/Makefile.in | 5 +- source3/smbd/globals.h | 11 ++++ source3/smbd/smb2_server.c | 114 ++++++++++++++++++++++------------- source3/smbd/smb2_sesssetup.c | 70 ++++++++++++++++++---- source3/smbd/smb2_signing.c | 135 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 280 insertions(+), 55 deletions(-) create mode 100644 source3/smbd/smb2_signing.c diff --git a/source3/Makefile.in b/source3/Makefile.in index 1120092f90..2b30b4a5bd 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -359,7 +359,8 @@ UTIL_OBJ = ../lib/util/rbtree.o ../lib/util/signal.o ../lib/util/time.o \ CRYPTO_OBJ = ../lib/crypto/crc32.o ../lib/crypto/md5.o \ ../lib/crypto/hmacmd5.o ../lib/crypto/arcfour.o \ - ../lib/crypto/md4.o + ../lib/crypto/md4.o \ + ../lib/crypto/sha256.o ../lib/crypto/hmacsha256.o LIB_OBJ = $(LIBSAMBAUTIL_OBJ) $(UTIL_OBJ) $(CRYPTO_OBJ) \ lib/messages.o librpc/gen_ndr/ndr_messaging.o lib/messages_local.o \ @@ -750,7 +751,7 @@ SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \ smbd/dnsregister.o smbd/globals.o \ smbd/smb2_server.o smbd/smb2_negprot.o \ smbd/smb2_sesssetup.o smbd/smb2_tcon.o \ - smbd/smb2_keepalive.o \ + smbd/smb2_keepalive.o smbd/smb2_signing.o \ $(MANGLE_OBJ) @VFS_STATIC@ SMBD_OBJ_BASE = $(PARAM_WITHOUT_REG_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \ diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index 9d5eead939..c6ab31dc36 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -206,6 +206,13 @@ struct smbd_smb2_tcon; DATA_BLOB negprot_spnego(void); +NTSTATUS smb2_signing_sign_pdu(DATA_BLOB session_key, + struct iovec *vector, + int count); +NTSTATUS smb2_signing_check_pdu(DATA_BLOB session_key, + const struct iovec *vector, + int count); + bool smbd_is_smb2_header(const uint8_t *inbuf, size_t size); void reply_smb2002(struct smb_request *req, uint16_t choice); @@ -244,6 +251,7 @@ struct smbd_smb2_request { struct smbd_smb2_tcon *tcon; int current_idx; + bool do_signing; struct { /* the NBT header is not allocated */ @@ -299,6 +307,9 @@ struct smbd_smb2_session { NTSTATUS status; uint64_t vuid; AUTH_NTLMSSP_STATE *auth_ntlmssp_state; + struct auth_serversupplied_info *server_info; + DATA_BLOB session_key; + bool do_signing; struct { /* an id tree used to allocate tids */ diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index 32bb5543ae..562fc567cc 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -288,14 +288,45 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) const uint8_t *inhdr; int i = req->current_idx; uint16_t opcode; + uint32_t flags; NTSTATUS status; + NTSTATUS session_status; inhdr = (const uint8_t *)req->in.vector[i].iov_base; /* TODO: verify more things */ + flags = IVAL(inhdr, SMB2_HDR_FLAGS); opcode = IVAL(inhdr, SMB2_HDR_OPCODE); DEBUG(10,("smbd_smb2_request_dispatch: opcode[%u]\n", opcode)); + +#define TMP_SMB2_ALLOWED_FLAGS ( \ + SMB2_HDR_FLAG_CHAINED | \ + SMB2_HDR_FLAG_SIGNED | \ + SMB2_HDR_FLAG_DFS) + if ((flags & ~TMP_SMB2_ALLOWED_FLAGS) != 0) { + return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); + } +#undef TMP_SMB2_ALLOWED_FLAGS + + session_status = smbd_smb2_request_check_session(req); + + req->do_signing = false; + if (flags & SMB2_HDR_FLAG_SIGNED) { + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); + } + + req->do_signing = true; + status = smb2_signing_check_pdu(req->session->session_key, + &req->in.vector[i], 3); + if (!NT_STATUS_IS_OK(status)) { + return smbd_smb2_request_error(req, status); + } + } else if (req->session && req->session->do_signing) { + return smbd_smb2_request_error(req, NT_STATUS_ACCESS_DENIED); + } + switch (opcode) { case SMB2_OP_NEGPROT: return smbd_smb2_request_process_negprot(req); @@ -304,13 +335,15 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) return smbd_smb2_request_process_sesssetup(req); case SMB2_OP_LOGOFF: - status = smbd_smb2_request_check_session(req); - if (!NT_STATUS_IS_OK(status)) { - return smbd_smb2_request_error(req, status); + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); } return smbd_smb2_request_process_logoff(req); case SMB2_OP_TCON: + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); + } status = smbd_smb2_request_check_session(req); if (!NT_STATUS_IS_OK(status)) { return smbd_smb2_request_error(req, status); @@ -318,9 +351,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) return smbd_smb2_request_process_tcon(req); case SMB2_OP_TDIS: - status = smbd_smb2_request_check_session(req); - if (!NT_STATUS_IS_OK(status)) { - return smbd_smb2_request_error(req, status); + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); } status = smbd_smb2_request_check_tcon(req); if (!NT_STATUS_IS_OK(status)) { @@ -329,9 +361,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) return smbd_smb2_request_process_tdis(req); case SMB2_OP_CREATE: - status = smbd_smb2_request_check_session(req); - if (!NT_STATUS_IS_OK(status)) { - return smbd_smb2_request_error(req, status); + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); } status = smbd_smb2_request_check_tcon(req); if (!NT_STATUS_IS_OK(status)) { @@ -340,9 +371,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED); case SMB2_OP_CLOSE: - status = smbd_smb2_request_check_session(req); - if (!NT_STATUS_IS_OK(status)) { - return smbd_smb2_request_error(req, status); + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); } status = smbd_smb2_request_check_tcon(req); if (!NT_STATUS_IS_OK(status)) { @@ -351,9 +381,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED); case SMB2_OP_FLUSH: - status = smbd_smb2_request_check_session(req); - if (!NT_STATUS_IS_OK(status)) { - return smbd_smb2_request_error(req, status); + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); } status = smbd_smb2_request_check_tcon(req); if (!NT_STATUS_IS_OK(status)) { @@ -362,9 +391,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED); case SMB2_OP_READ: - status = smbd_smb2_request_check_session(req); - if (!NT_STATUS_IS_OK(status)) { - return smbd_smb2_request_error(req, status); + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); } status = smbd_smb2_request_check_tcon(req); if (!NT_STATUS_IS_OK(status)) { @@ -373,9 +401,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED); case SMB2_OP_WRITE: - status = smbd_smb2_request_check_session(req); - if (!NT_STATUS_IS_OK(status)) { - return smbd_smb2_request_error(req, status); + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); } status = smbd_smb2_request_check_tcon(req); if (!NT_STATUS_IS_OK(status)) { @@ -384,9 +411,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED); case SMB2_OP_LOCK: - status = smbd_smb2_request_check_session(req); - if (!NT_STATUS_IS_OK(status)) { - return smbd_smb2_request_error(req, status); + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); } status = smbd_smb2_request_check_tcon(req); if (!NT_STATUS_IS_OK(status)) { @@ -395,9 +421,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED); case SMB2_OP_IOCTL: - status = smbd_smb2_request_check_session(req); - if (!NT_STATUS_IS_OK(status)) { - return smbd_smb2_request_error(req, status); + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); } status = smbd_smb2_request_check_tcon(req); if (!NT_STATUS_IS_OK(status)) { @@ -412,9 +437,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) return smbd_smb2_request_process_keepalive(req); case SMB2_OP_FIND: - status = smbd_smb2_request_check_session(req); - if (!NT_STATUS_IS_OK(status)) { - return smbd_smb2_request_error(req, status); + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); } status = smbd_smb2_request_check_tcon(req); if (!NT_STATUS_IS_OK(status)) { @@ -423,9 +447,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED); case SMB2_OP_NOTIFY: - status = smbd_smb2_request_check_session(req); - if (!NT_STATUS_IS_OK(status)) { - return smbd_smb2_request_error(req, status); + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); } status = smbd_smb2_request_check_tcon(req); if (!NT_STATUS_IS_OK(status)) { @@ -434,9 +457,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED); case SMB2_OP_GETINFO: - status = smbd_smb2_request_check_session(req); - if (!NT_STATUS_IS_OK(status)) { - return smbd_smb2_request_error(req, status); + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); } status = smbd_smb2_request_check_tcon(req); if (!NT_STATUS_IS_OK(status)) { @@ -445,9 +467,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED); case SMB2_OP_SETINFO: - status = smbd_smb2_request_check_session(req); - if (!NT_STATUS_IS_OK(status)) { - return smbd_smb2_request_error(req, status); + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); } status = smbd_smb2_request_check_tcon(req); if (!NT_STATUS_IS_OK(status)) { @@ -456,9 +477,8 @@ static NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) return smbd_smb2_request_error(req, NT_STATUS_NOT_IMPLEMENTED); case SMB2_OP_BREAK: - status = smbd_smb2_request_check_session(req); - if (!NT_STATUS_IS_OK(status)) { - return smbd_smb2_request_error(req, status); + if (!NT_STATUS_IS_OK(session_status)) { + return smbd_smb2_request_error(req, session_status); } status = smbd_smb2_request_check_tcon(req); if (!NT_STATUS_IS_OK(status)) { @@ -481,6 +501,16 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req) smb2_setup_nbt_length(req->out.vector, req->out.vector_count); + if (req->do_signing) { + int i = req->current_idx; + NTSTATUS status; + status = smb2_signing_sign_pdu(req->session->session_key, + &req->out.vector[i], 3); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } + req->current_idx += 3; if (req->current_idx > req->in.vector_count) { diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c index fafda24ca4..be37aec04d 100644 --- a/source3/smbd/smb2_sesssetup.c +++ b/source3/smbd/smb2_sesssetup.c @@ -24,7 +24,9 @@ static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *req, uint64_t in_session_id, + uint8_t in_security_mode, DATA_BLOB in_security_buffer, + uint16_t *out_session_flags, DATA_BLOB *out_security_buffer, uint64_t *out_session_id); @@ -39,9 +41,11 @@ NTSTATUS smbd_smb2_request_process_sesssetup(struct smbd_smb2_request *req) size_t expected_body_size = 0x19; size_t body_size; uint64_t in_session_id; + uint8_t in_security_mode; uint16_t in_security_offset; uint16_t in_security_length; DATA_BLOB in_security_buffer; + uint16_t out_session_flags; uint64_t out_session_id; uint16_t out_security_offset; DATA_BLOB out_security_buffer; @@ -72,12 +76,15 @@ NTSTATUS smbd_smb2_request_process_sesssetup(struct smbd_smb2_request *req) } in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID); + in_security_mode = CVAL(inbody, 0x03); in_security_buffer.data = (uint8_t *)req->in.vector[i+2].iov_base; in_security_buffer.length = in_security_length; status = smbd_smb2_session_setup(req, in_session_id, + in_security_mode, in_security_buffer, + &out_session_flags, &out_security_buffer, &out_session_id); if (!NT_STATUS_IS_OK(status) && @@ -98,7 +105,8 @@ NTSTATUS smbd_smb2_request_process_sesssetup(struct smbd_smb2_request *req) SBVAL(outhdr, SMB2_HDR_SESSION_ID, out_session_id); SSVAL(outbody.data, 0x00, 0x08 + 1); /* struct size */ - SSVAL(outbody.data, 0x02, 0); /* session flags */ + SSVAL(outbody.data, 0x02, + out_session_flags); /* session flags */ SSVAL(outbody.data, 0x04, out_security_offset); /* security buffer offset */ SSVAL(outbody.data, 0x06, @@ -132,13 +140,17 @@ static int smbd_smb2_session_destructor(struct smbd_smb2_session *session) static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *req, uint64_t in_session_id, + uint8_t in_security_mode, DATA_BLOB in_security_buffer, + uint16_t *out_session_flags, DATA_BLOB *out_security_buffer, uint64_t *out_session_id) { struct smbd_smb2_session *session; NTSTATUS status; + *out_session_flags = 0; + if (in_session_id == 0) { int id; @@ -185,6 +197,7 @@ static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *req, if (session->auth_ntlmssp_state == NULL) { status = auth_ntlmssp_start(&session->auth_ntlmssp_state); if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(session); return status; } } @@ -193,19 +206,54 @@ static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *req, in_security_buffer, out_security_buffer); if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - /* nothing to do */ - } else if (NT_STATUS_IS_OK(status)) { - /* TODO: setup session key for signing */ - session->status = NT_STATUS_OK; - /* - * we attach the session to the request - * so that the response can be signed - */ - req->session = session; - } else { + *out_session_id = session->vuid; + return status; + } else if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(session); return status; } + /* TODO: setup session key for signing */ + + if ((in_security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) || + lp_server_signing() == Required) { + session->do_signing = true; + } + + if (session->auth_ntlmssp_state->server_info->guest) { + /* we map anonymous to guest internally */ + *out_session_flags |= SMB2_SESSION_FLAG_IS_GUEST; + *out_session_flags |= SMB2_SESSION_FLAG_IS_NULL; + /* force no signing */ + session->do_signing = false; + } + + session->server_info = session->auth_ntlmssp_state->server_info; + data_blob_free(&session->server_info->user_session_key); + session->server_info->user_session_key = + data_blob_talloc( + session->server_info, + session->auth_ntlmssp_state->ntlmssp_state->session_key.data, + session->auth_ntlmssp_state->ntlmssp_state->session_key.length); + if (session->auth_ntlmssp_state->ntlmssp_state->session_key.length > 0) { + if (session->server_info->user_session_key.data == NULL) { + TALLOC_FREE(session); + return NT_STATUS_NO_MEMORY; + } + } + session->session_key = session->server_info->user_session_key; + + session->status = NT_STATUS_OK; + + /* + * we attach the session to the request + * so that the response can be signed + */ + req->session = session; + if (session->do_signing) { + req->do_signing = true; + } + *out_session_id = session->vuid; return status; } diff --git a/source3/smbd/smb2_signing.c b/source3/smbd/smb2_signing.c new file mode 100644 index 0000000000..55ed4f6d1c --- /dev/null +++ b/source3/smbd/smb2_signing.c @@ -0,0 +1,135 @@ +/* + Unix SMB/CIFS implementation. + SMB2 signing + + Copyright (C) Stefan Metzmacher 2009 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "smbd/globals.h" +#include "../source4/libcli/smb2/smb2_constants.h" +#include "../lib/crypto/crypto.h" + +NTSTATUS smb2_signing_sign_pdu(DATA_BLOB session_key, + struct iovec *vector, + int count) +{ + uint8_t *hdr; + uint64_t session_id; + struct HMACSHA256Context m; + uint8_t res[SHA256_DIGEST_LENGTH]; + int i; + + if (count < 2) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (vector[0].iov_len != SMB2_HDR_BODY) { + return NT_STATUS_INVALID_PARAMETER; + } + + hdr = (uint8_t *)vector[0].iov_base; + + session_id = BVAL(hdr, SMB2_HDR_SESSION_ID); + if (session_id == 0) { + /* + * do not sign messages with a zero session_id. + * See MS-SMB2 3.2.4.1.1 + */ + return NT_STATUS_OK; + } + + if (session_key.length == 0) { + DEBUG(2,("Wrong session key length %u for SMB2 signing\n", + (unsigned)session_key.length)); + return NT_STATUS_ACCESS_DENIED; + } + + memset(hdr + SMB2_HDR_SIGNATURE, 0, 16); + + SIVAL(hdr, SMB2_HDR_FLAGS, IVAL(hdr, SMB2_HDR_FLAGS) | SMB2_HDR_FLAG_SIGNED); + + ZERO_STRUCT(m); + hmac_sha256_init(session_key.data, MIN(session_key.length, 16), &m); + for (i=0; i < count; i++) { + hmac_sha256_update((const uint8_t *)vector[i].iov_base, + vector[i].iov_len, &m); + } + hmac_sha256_final(res, &m); + DEBUG(5,("signed SMB2 message\n")); + + memcpy(hdr + SMB2_HDR_SIGNATURE, res, 16); + + return NT_STATUS_OK; +} + +NTSTATUS smb2_signing_check_pdu(DATA_BLOB session_key, + const struct iovec *vector, + int count) +{ + const uint8_t *hdr; + const uint8_t *sig; + uint64_t session_id; + struct HMACSHA256Context m; + uint8_t res[SHA256_DIGEST_LENGTH]; + static const uint8_t zero_sig[16]; + int i; + + if (count < 2) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (vector[0].iov_len != SMB2_HDR_BODY) { + return NT_STATUS_INVALID_PARAMETER; + } + + hdr = (const uint8_t *)vector[0].iov_base; + + session_id = BVAL(hdr, SMB2_HDR_SESSION_ID); + if (session_id == 0) { + /* + * do not sign messages with a zero session_id. + * See MS-SMB2 3.2.4.1.1 + */ + return NT_STATUS_OK; + } + + if (session_key.length == 0) { + /* we don't have the session key yet */ + return NT_STATUS_OK; + } + + sig = hdr+SMB2_HDR_SIGNATURE; + + ZERO_STRUCT(m); + hmac_sha256_init(session_key.data, MIN(session_key.length, 16), &m); + hmac_sha256_update(hdr, SMB2_HDR_SIGNATURE, &m); + hmac_sha256_update(zero_sig, 16, &m); + for (i=1; i < count; i++) { + hmac_sha256_update((const uint8_t *)vector[i].iov_base, + vector[i].iov_len, &m); + } + hmac_sha256_final(res, &m); + + if (memcmp(res, sig, 16) != 0) { + DEBUG(0,("Bad SMB2 signature for message\n")); + dump_data(0, sig, 16); + dump_data(0, res, 16); + return NT_STATUS_ACCESS_DENIED; + } + + return NT_STATUS_OK; +} -- cgit From ebc860ebeb7ebaeceae2534faeee49d062f29db8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 26 May 2009 10:48:12 +0200 Subject: s3:smbd: move SMB1 specific stuff into a substructure of smbd_server_connection metze --- source3/smbd/globals.h | 8 +++++--- source3/smbd/process.c | 18 +++++++++--------- source3/smbd/reply.c | 4 ++-- source3/smbd/signing.c | 26 +++++++++++++------------- source3/smbd/smb2_server.c | 2 +- 5 files changed, 30 insertions(+), 28 deletions(-) diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index c6ab31dc36..fb733355d7 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -330,10 +330,12 @@ struct smbd_smb2_tcon { }; struct smbd_server_connection { - struct fd_event *fde; - uint64_t num_requests; - struct smb_signing_state *signing_state; bool allow_smb2; + struct { + struct fd_event *fde; + uint64_t num_requests; + struct smb_signing_state *signing_state; + } smb1; struct { struct tevent_context *event_ctx; struct tevent_queue *recv_queue; diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 5cad8bfc9a..e014965147 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -1462,7 +1462,7 @@ static void process_smb(struct smbd_server_connection *conn, trans_num++; done: - conn->num_requests++; + conn->smb1.num_requests++; /* The timeout_processing function isn't run nearly often enough to implement 'max log size' without @@ -1471,7 +1471,7 @@ done: level 10. Checking every 50 SMBs is a nice tradeoff of performance vs log file size overrun. */ - if ((conn->num_requests % 50) == 0 && + if ((conn->smb1.num_requests % 50) == 0 && need_to_check_log_size()) { change_to_root_user(); check_log_size(); @@ -2158,13 +2158,13 @@ void smbd_process(void) max_recv = MIN(lp_maxxmit(),BUFFER_SIZE); - smbd_server_conn->fde = event_add_fd(smbd_event_context(), - smbd_server_conn, - smbd_server_fd(), - EVENT_FD_READ, - smbd_server_connection_handler, - smbd_server_conn); - if (!smbd_server_conn->fde) { + smbd_server_conn->smb1.fde = event_add_fd(smbd_event_context(), + smbd_server_conn, + smbd_server_fd(), + EVENT_FD_READ, + smbd_server_connection_handler, + smbd_server_conn); + if (!smbd_server_conn->smb1.fde) { exit_server("failed to create smbd_server_connection fde"); } diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index d5ee918b82..a21c2cfca1 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -2893,7 +2893,7 @@ static void send_file_readbraw(connection_struct *conn, if ( !req_is_in_chain(req) && (nread > 0) && (fsp->base_fsp == NULL) && (fsp->wcp == NULL) && - lp_use_sendfile(SNUM(conn), smbd_server_conn->signing_state) ) { + lp_use_sendfile(SNUM(conn), smbd_server_conn->smb1.signing_state) ) { ssize_t sendfile_read = -1; char header[4]; DATA_BLOB header_blob; @@ -3412,7 +3412,7 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req, if (!req_is_in_chain(req) && !is_encrypted_packet(req->inbuf) && (fsp->base_fsp == NULL) && (fsp->wcp == NULL) && - lp_use_sendfile(SNUM(conn), smbd_server_conn->signing_state) ) { + lp_use_sendfile(SNUM(conn), smbd_server_conn->smb1.signing_state) ) { uint8 headerbuf[smb_size + 12 * 2]; DATA_BLOB header; diff --git a/source3/smbd/signing.c b/source3/smbd/signing.c index b56eb71f45..9b5e3452f9 100644 --- a/source3/smbd/signing.c +++ b/source3/smbd/signing.c @@ -35,8 +35,8 @@ bool srv_check_sign_mac(struct smbd_server_connection *conn, return true; } - *seqnum = smb_signing_next_seqnum(conn->signing_state, false); - return smb_signing_check_pdu(conn->signing_state, + *seqnum = smb_signing_next_seqnum(conn->smb1.signing_state, false); + return smb_signing_check_pdu(conn->smb1.signing_state, (const uint8_t *)inbuf, *seqnum); } @@ -53,7 +53,7 @@ void srv_calculate_sign_mac(struct smbd_server_connection *conn, return; } - smb_signing_sign_pdu(conn->signing_state, (uint8_t *)outbuf, seqnum); + smb_signing_sign_pdu(conn->smb1.signing_state, (uint8_t *)outbuf, seqnum); } @@ -62,7 +62,7 @@ void srv_calculate_sign_mac(struct smbd_server_connection *conn, ************************************************************/ void srv_cancel_sign_response(struct smbd_server_connection *conn) { - smb_signing_cancel_reply(conn->signing_state, true); + smb_signing_cancel_reply(conn->smb1.signing_state, true); } /*********************************************************** @@ -87,9 +87,9 @@ bool srv_init_signing(struct smbd_server_connection *conn) break; } - conn->signing_state = smb_signing_init(smbd_event_context(), - allowed, mandatory); - if (!conn->signing_state) { + conn->smb1.signing_state = smb_signing_init(smbd_event_context(), + allowed, mandatory); + if (!conn->smb1.signing_state) { return false; } @@ -98,7 +98,7 @@ bool srv_init_signing(struct smbd_server_connection *conn) void srv_set_signing_negotiated(struct smbd_server_connection *conn) { - smb_signing_set_negotiated(conn->signing_state); + smb_signing_set_negotiated(conn->smb1.signing_state); } /*********************************************************** @@ -108,7 +108,7 @@ void srv_set_signing_negotiated(struct smbd_server_connection *conn) bool srv_is_signing_active(struct smbd_server_connection *conn) { - return smb_signing_is_active(conn->signing_state); + return smb_signing_is_active(conn->smb1.signing_state); } @@ -119,7 +119,7 @@ bool srv_is_signing_active(struct smbd_server_connection *conn) bool srv_is_signing_negotiated(struct smbd_server_connection *conn) { - return smb_signing_is_negotiated(conn->signing_state); + return smb_signing_is_negotiated(conn->smb1.signing_state); } /*********************************************************** @@ -136,8 +136,8 @@ void srv_set_signing(struct smbd_server_connection *conn, if (!user_session_key.length) return; - negotiated = smb_signing_is_negotiated(conn->signing_state); - mandatory = smb_signing_is_mandatory(conn->signing_state); + negotiated = smb_signing_is_negotiated(conn->smb1.signing_state); + mandatory = smb_signing_is_mandatory(conn->smb1.signing_state); if (!negotiated && !mandatory) { DEBUG(5,("srv_set_signing: signing negotiated = %u, " @@ -146,7 +146,7 @@ void srv_set_signing(struct smbd_server_connection *conn, return; } - if (!smb_signing_activate(conn->signing_state, + if (!smb_signing_activate(conn->smb1.signing_state, user_session_key, response)) { return; } diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index 562fc567cc..0d901714e0 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -41,7 +41,7 @@ static NTSTATUS smbd_initialize_smb2(struct smbd_server_connection *conn) NTSTATUS status; int ret; - TALLOC_FREE(conn->fde); + TALLOC_FREE(conn->smb1.fde); conn->smb2.event_ctx = smbd_event_context(); -- cgit From 73eaff7a395c9a7a0042f2c50f8817499b6cfdcd Mon Sep 17 00:00:00 2001 From: Karolin Seeger Date: Tue, 26 May 2009 14:16:10 +0200 Subject: s3/docs: Fix typo in man idmap_rid. Karolin --- docs-xml/manpages-3/idmap_rid.8.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-xml/manpages-3/idmap_rid.8.xml b/docs-xml/manpages-3/idmap_rid.8.xml index 5449797441..55aed62f85 100644 --- a/docs-xml/manpages-3/idmap_rid.8.xml +++ b/docs-xml/manpages-3/idmap_rid.8.xml @@ -66,7 +66,7 @@ - Correspondingly, the formula for calculationg the RID for a + Correspondingly, the formula for calculating the RID for a given Unix ID is this: RID = ID + BASE_RID - LOW_RANGE_ID. -- cgit From 6b7bd3757005286c528d3bb0c6790e0d8651eaaf Mon Sep 17 00:00:00 2001 From: Andrew Kroeger Date: Mon, 25 May 2009 14:46:08 -0500 Subject: gitignore: Ignore additional auto-generated files. Corrected path to tdr_proto.h and added librpc/gen_ndr/{cli,srv}_dcerpc.[ch]. --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 45164d2985..5d18b2d6f9 100644 --- a/.gitignore +++ b/.gitignore @@ -232,7 +232,7 @@ source4/lib/tdb/bin/tdbbackup source4/lib/tdb/bin/tdbdump source4/lib/tdb/bin/tdbtool source4/lib/tdb/bin/tdbtorture -source4/lib/tdr/tdr_proto.h +lib/tdr/tdr_proto.h lib/util/apidocs lib/util/asn1_proto.h lib/util/pidfile.h @@ -316,6 +316,8 @@ librpc/gen_ndr/cli_drsblobs.h librpc/gen_ndr/srv_drsblobs.c librpc/gen_ndr/srv_drsblobs.h source3/setup +librpc/gen_ndr/cli_dcerpc.[ch] +librpc/gen_ndr/srv_dcerpc.[ch] librpc/gen_ndr/*wzcsvc* librpc/gen_ndr/*w32time* librpc/gen_ndr/*wmi* -- cgit From caeae66c5bb3a4a600b5c90be97d98a323d1dc2f Mon Sep 17 00:00:00 2001 From: Björn Jacke Date: Tue, 26 May 2009 15:40:21 +0200 Subject: s3:pam_smbpass: don't call openlog() or closelog() from pam_smbpass Patch from Steve Langasek with tiny fixes by me to make it apply to master. Also see Debian bug #434372 and bugzilla #4831. Calling openlog() or closelog() inside a pam module is not good as these functions are not stackable and no program won't re-do openlog() just because a pam module might have called closelog(). --- source3/pam_smbpass/pam_smb_acct.c | 17 +++--- source3/pam_smbpass/pam_smb_auth.c | 19 ++++--- source3/pam_smbpass/pam_smb_passwd.c | 40 +++++++------- source3/pam_smbpass/support.c | 102 ++++++++++++++++++++++------------- source3/pam_smbpass/support.h | 6 +-- 5 files changed, 104 insertions(+), 80 deletions(-) diff --git a/source3/pam_smbpass/pam_smb_acct.c b/source3/pam_smbpass/pam_smb_acct.c index 2a8bd26597..9ad74788f0 100644 --- a/source3/pam_smbpass/pam_smb_acct.c +++ b/source3/pam_smbpass/pam_smb_acct.c @@ -58,26 +58,25 @@ int pam_sm_acct_mgmt( pam_handle_t *pamh, int flags, /* Samba initialization. */ load_case_tables(); - setup_logging( "pam_smbpass", False ); lp_set_in_client(True); - ctrl = set_ctrl( flags, argc, argv ); + ctrl = set_ctrl(pamh, flags, argc, argv ); /* get the username */ retval = pam_get_user( pamh, &name, "Username: " ); if (retval != PAM_SUCCESS) { if (on( SMB_DEBUG, ctrl )) { - _log_err( LOG_DEBUG, "acct: could not identify user" ); + _log_err(pamh, LOG_DEBUG, "acct: could not identify user" ); } return retval; } if (on( SMB_DEBUG, ctrl )) { - _log_err( LOG_DEBUG, "acct: username [%s] obtained", name ); + _log_err(pamh, LOG_DEBUG, "acct: username [%s] obtained", name ); } if (geteuid() != 0) { - _log_err( LOG_DEBUG, "Cannot access samba password database, not running as root."); + _log_err(pamh, LOG_DEBUG, "Cannot access samba password database, not running as root."); return PAM_AUTHINFO_UNAVAIL; } @@ -85,7 +84,7 @@ int pam_sm_acct_mgmt( pam_handle_t *pamh, int flags, from a SIGPIPE it's not expecting */ oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN); if (!initialize_password_db(True, NULL)) { - _log_err( LOG_ALERT, "Cannot access samba password database" ); + _log_err(pamh, LOG_ALERT, "Cannot access samba password database" ); CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return PAM_AUTHINFO_UNAVAIL; } @@ -99,7 +98,7 @@ int pam_sm_acct_mgmt( pam_handle_t *pamh, int flags, } if (!pdb_getsampwnam(sampass, name )) { - _log_err( LOG_DEBUG, "acct: could not identify user" ); + _log_err(pamh, LOG_DEBUG, "acct: could not identify user"); CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return PAM_USER_UNKNOWN; } @@ -112,8 +111,8 @@ int pam_sm_acct_mgmt( pam_handle_t *pamh, int flags, if (pdb_get_acct_ctrl(sampass) & ACB_DISABLED) { if (on( SMB_DEBUG, ctrl )) { - _log_err( LOG_DEBUG - , "acct: account %s is administratively disabled", name ); + _log_err(pamh, LOG_DEBUG, + "acct: account %s is administratively disabled", name); } make_remark( pamh, ctrl, PAM_ERROR_MSG , "Your account has been disabled; " diff --git a/source3/pam_smbpass/pam_smb_auth.c b/source3/pam_smbpass/pam_smb_auth.c index b5a6a473b6..88ff9851f5 100644 --- a/source3/pam_smbpass/pam_smb_auth.c +++ b/source3/pam_smbpass/pam_smb_auth.c @@ -81,10 +81,9 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, /* Samba initialization. */ load_case_tables(); - setup_logging("pam_smbpass",False); lp_set_in_client(True); - ctrl = set_ctrl(flags, argc, argv); + ctrl = set_ctrl(pamh, flags, argc, argv); /* Get a few bytes so we can pass our return value to pam_sm_setcred(). */ @@ -99,29 +98,29 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, retval = pam_get_user( pamh, &name, "Username: " ); if ( retval != PAM_SUCCESS ) { if (on( SMB_DEBUG, ctrl )) { - _log_err(LOG_DEBUG, "auth: could not identify user"); + _log_err(pamh, LOG_DEBUG, "auth: could not identify user"); } AUTH_RETURN; } if (on( SMB_DEBUG, ctrl )) { - _log_err( LOG_DEBUG, "username [%s] obtained", name ); + _log_err(pamh, LOG_DEBUG, "username [%s] obtained", name ); } if (geteuid() != 0) { - _log_err( LOG_DEBUG, "Cannot access samba password database, not running as root."); + _log_err(pamh, LOG_DEBUG, "Cannot access samba password database, not running as root."); retval = PAM_AUTHINFO_UNAVAIL; AUTH_RETURN; } if (!initialize_password_db(True, NULL)) { - _log_err( LOG_ALERT, "Cannot access samba password database" ); + _log_err(pamh, LOG_ALERT, "Cannot access samba password database" ); retval = PAM_AUTHINFO_UNAVAIL; AUTH_RETURN; } sampass = samu_new( NULL ); if (!sampass) { - _log_err( LOG_ALERT, "Cannot talloc a samu struct" ); + _log_err(pamh, LOG_ALERT, "Cannot talloc a samu struct" ); retval = nt_status_to_pam(NT_STATUS_NO_MEMORY); AUTH_RETURN; } @@ -135,7 +134,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, } if (!found) { - _log_err(LOG_ALERT, "Failed to find entry for user %s.", name); + _log_err(pamh, LOG_ALERT, "Failed to find entry for user %s.", name); retval = PAM_USER_UNKNOWN; TALLOC_FREE(sampass); sampass = NULL; @@ -154,7 +153,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, retval = _smb_read_password(pamh, ctrl, NULL, "Password: ", NULL, _SMB_AUTHTOK, &p); if (retval != PAM_SUCCESS ) { - _log_err(LOG_CRIT, "auth: no password provided for [%s]", name); + _log_err(pamh,LOG_CRIT, "auth: no password provided for [%s]", name); TALLOC_FREE(sampass); AUTH_RETURN; } @@ -202,7 +201,7 @@ static int _smb_add_user(pam_handle_t *pamh, unsigned int ctrl, retval = _pam_get_item( pamh, PAM_AUTHTOK, &pass ); if (retval != PAM_SUCCESS) { - _log_err( LOG_ALERT + _log_err(pamh, LOG_ALERT , "pam_get_item returned error to pam_sm_authenticate" ); return PAM_AUTHTOK_RECOVER_ERR; } else if (pass == NULL) { diff --git a/source3/pam_smbpass/pam_smb_passwd.c b/source3/pam_smbpass/pam_smb_passwd.c index dce6e01ae9..9504e4d53c 100644 --- a/source3/pam_smbpass/pam_smb_passwd.c +++ b/source3/pam_smbpass/pam_smb_passwd.c @@ -106,10 +106,9 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags, /* Samba initialization. */ load_case_tables(); - setup_logging( "pam_smbpass", False ); lp_set_in_client(True); - ctrl = set_ctrl(flags, argc, argv); + ctrl = set_ctrl(pamh, flags, argc, argv); /* * First get the name of a user. No need to do anything if we can't @@ -119,16 +118,16 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags, retval = pam_get_user( pamh, &user, "Username: " ); if (retval != PAM_SUCCESS) { if (on( SMB_DEBUG, ctrl )) { - _log_err( LOG_DEBUG, "password: could not identify user" ); + _log_err(pamh, LOG_DEBUG, "password: could not identify user"); } return retval; } if (on( SMB_DEBUG, ctrl )) { - _log_err( LOG_DEBUG, "username [%s] obtained", user ); + _log_err(pamh, LOG_DEBUG, "username [%s] obtained", user); } if (geteuid() != 0) { - _log_err( LOG_DEBUG, "Cannot access samba password database, not running as root."); + _log_err(pamh, LOG_DEBUG, "Cannot access samba password database, not running as root."); return PAM_AUTHINFO_UNAVAIL; } @@ -137,7 +136,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags, oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN); if (!initialize_password_db(False, NULL)) { - _log_err( LOG_ALERT, "Cannot access samba password database" ); + _log_err(pamh, LOG_ALERT, "Cannot access samba password database" ); CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return PAM_AUTHINFO_UNAVAIL; } @@ -149,12 +148,12 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags, } if (!pdb_getsampwnam(sampass,user)) { - _log_err( LOG_ALERT, "Failed to find entry for user %s.", user ); + _log_err(pamh, LOG_ALERT, "Failed to find entry for user %s.", user); CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return PAM_USER_UNKNOWN; } if (on( SMB_DEBUG, ctrl )) { - _log_err( LOG_DEBUG, "Located account for %s", user ); + _log_err(pamh, LOG_DEBUG, "Located account for %s", user); } if (flags & PAM_PRELIM_CHECK) { @@ -180,7 +179,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags, #define greeting "Changing password for " Announce = SMB_MALLOC_ARRAY(char, sizeof(greeting)+strlen(user)); if (Announce == NULL) { - _log_err(LOG_CRIT, "password: out of memory"); + _log_err(pamh, LOG_CRIT, "password: out of memory"); TALLOC_FREE(sampass); CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return PAM_BUF_ERR; @@ -195,8 +194,8 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags, SAFE_FREE( Announce ); if (retval != PAM_SUCCESS) { - _log_err( LOG_NOTICE - , "password - (old) token not obtained" ); + _log_err(pamh, LOG_NOTICE, + "password - (old) token not obtained"); TALLOC_FREE(sampass); CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return retval; @@ -241,7 +240,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags, } if (retval != PAM_SUCCESS) { - _log_err( LOG_NOTICE, "password: user not authenticated" ); + _log_err(pamh, LOG_NOTICE, "password: user not authenticated"); TALLOC_FREE(sampass); CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); return retval; @@ -266,8 +265,8 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags, if (retval != PAM_SUCCESS) { if (on( SMB_DEBUG, ctrl )) { - _log_err( LOG_ALERT - , "password: new password not obtained" ); + _log_err(pamh, LOG_ALERT, + "password: new password not obtained"); } pass_old = NULL; /* tidy up */ TALLOC_FREE(sampass); @@ -288,7 +287,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags, retval = _pam_smb_approve_pass(pamh, ctrl, pass_old, pass_new); if (retval != PAM_SUCCESS) { - _log_err(LOG_NOTICE, "new password not acceptable"); + _log_err(pamh, LOG_NOTICE, "new password not acceptable"); pass_new = pass_old = NULL; /* tidy up */ TALLOC_FREE(sampass); CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler); @@ -308,16 +307,17 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags, /* password updated */ if (!sid_to_uid(pdb_get_user_sid(sampass), &uid)) { - _log_err( LOG_NOTICE, "Unable to get uid for user %s", + _log_err(pamh, LOG_NOTICE, + "Unable to get uid for user %s", pdb_get_username(sampass)); - _log_err( LOG_NOTICE, "password for (%s) changed by (%s/%d)", + _log_err(pamh, LOG_NOTICE, "password for (%s) changed by (%s/%d)", user, uidtoname(getuid()), getuid()); } else { - _log_err( LOG_NOTICE, "password for (%s/%d) changed by (%s/%d)", + _log_err(pamh, LOG_NOTICE, "password for (%s/%d) changed by (%s/%d)", user, uid, uidtoname(getuid()), getuid()); } } else { - _log_err( LOG_ERR, "password change failed for user %s", user); + _log_err(pamh, LOG_ERR, "password change failed for user %s", user); } pass_old = pass_new = NULL; @@ -328,7 +328,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags, } else { /* something has broken with the library */ - _log_err( LOG_ALERT, "password received unknown request" ); + _log_err(pamh, LOG_ALERT, "password received unknown request"); retval = PAM_ABORT; } diff --git a/source3/pam_smbpass/support.c b/source3/pam_smbpass/support.c index b6cf3a886d..855885a6d7 100644 --- a/source3/pam_smbpass/support.c +++ b/source3/pam_smbpass/support.c @@ -14,6 +14,7 @@ * this program; if not, see . */ +#include "config.h" #include "includes.h" #include "general.h" @@ -64,17 +65,42 @@ void _cleanup(pam_handle_t *, void *, int); char *_pam_delete(register char *); /* syslogging function for errors and other information */ +#ifdef HAVE_PAM_VSYSLOG +void _log_err( pam_handle_t *pamh, int err, const char *format, ... ) +{ + va_list args; -void _log_err( int err, const char *format, ... ) + va_start(args, format); + pam_vsyslog(pamh, err, format, args); + va_end(args); +} +#else +void _log_err( pam_handle_t *pamh, int err, const char *format, ... ) { - va_list args; + va_list args; + const char tag[] = "(pam_smbpass) "; + char *mod_format; + + mod_format = SMB_MALLOC_ARRAY(char, sizeof(tag) + strlen(format)); + /* try really, really hard to log something, since this may have + been a message about a malloc() failure... */ + if (mod_format == NULL) { + va_start(args, format); + vsyslog(err | LOG_AUTH, format, args); + va_end(args); + return; + } - va_start( args, format ); - openlog( "PAM_smbpass", LOG_CONS | LOG_PID, LOG_AUTH ); - vsyslog( err, format, args ); - va_end( args ); - closelog(); + strncpy(mod_format, tag, strlen(tag)+1); + strncat(mod_format, format, strlen(format)); + + va_start(args, format); + vsyslog(err | LOG_AUTH, mod_format, args); + va_end(args); + + free(mod_format); } +#endif /* this is a front-end for module-application conversations */ @@ -92,11 +118,11 @@ int converse( pam_handle_t * pamh, int ctrl, int nargs ,response, conv->appdata_ptr); if (retval != PAM_SUCCESS && on(SMB_DEBUG, ctrl)) { - _log_err(LOG_DEBUG, "conversation failure [%s]" + _log_err(pamh, LOG_DEBUG, "conversation failure [%s]" ,pam_strerror(pamh, retval)); } } else { - _log_err(LOG_ERR, "couldn't obtain coversation function [%s]" + _log_err(pamh, LOG_ERR, "couldn't obtain coversation function [%s]" ,pam_strerror(pamh, retval)); } @@ -123,7 +149,7 @@ int make_remark( pam_handle_t * pamh, unsigned int ctrl /* set the control flags for the SMB module. */ -int set_ctrl( int flags, int argc, const char **argv ) +int set_ctrl( pam_handle_t *pamh, int flags, int argc, const char **argv ) { int i = 0; const char *service_file = NULL; @@ -165,7 +191,7 @@ int set_ctrl( int flags, int argc, const char **argv ) /* Read some options from the Samba config. Can be overridden by the PAM config. */ if(lp_load(service_file,True,False,False,True) == False) { - _log_err( LOG_ERR, "Error loading service file %s", service_file ); + _log_err(pamh, LOG_ERR, "Error loading service file %s", service_file); } secrets_init(); @@ -188,7 +214,7 @@ int set_ctrl( int flags, int argc, const char **argv ) } if (j >= SMB_CTRLS_) { - _log_err( LOG_ERR, "unrecognized option [%s]", *argv ); + _log_err(pamh, LOG_ERR, "unrecognized option [%s]", *argv); } else { ctrl &= smb_args[j].mask; /* for turning things off */ ctrl |= smb_args[j].flag; /* for turning things on */ @@ -227,7 +253,7 @@ void _cleanup( pam_handle_t * pamh, void *x, int error_status ) * evidence of old token around for later stack analysis. * */ -char * smbpXstrDup( const char *x ) +char * smbpXstrDup( pam_handle_t *pamh, const char *x ) { register char *newstr = NULL; @@ -237,7 +263,7 @@ char * smbpXstrDup( const char *x ) for (i = 0; x[i]; ++i); /* length of string */ if ((newstr = SMB_MALLOC_ARRAY(char, ++i)) == NULL) { i = 0; - _log_err( LOG_CRIT, "out of memory in smbpXstrDup" ); + _log_err(pamh, LOG_CRIT, "out of memory in smbpXstrDup"); } else { while (i-- > 0) { newstr[i] = x[i]; @@ -279,7 +305,7 @@ void _cleanup_failures( pam_handle_t * pamh, void *fl, int err ) /* log the number of authentication failures */ if (failure->count != 0) { _pam_get_item( pamh, PAM_SERVICE, &service ); - _log_err( LOG_NOTICE + _log_err(pamh, LOG_NOTICE , "%d authentication %s " "from %s for service %s as %s(%d)" , failure->count @@ -288,7 +314,7 @@ void _cleanup_failures( pam_handle_t * pamh, void *fl, int err ) , service == NULL ? "**unknown**" : service , failure->user, failure->id ); if (failure->count > SMB_MAX_RETRIES) { - _log_err( LOG_ALERT + _log_err(pamh, LOG_ALERT , "service(%s) ignoring max retries; %d > %d" , service == NULL ? "**unknown**" : service , failure->count @@ -324,8 +350,7 @@ int _smb_verify_password( pam_handle_t * pamh, struct samu *sampass, if (!pdb_get_nt_passwd(sampass)) { - _log_err( LOG_DEBUG, "user %s has null SMB password" - , name ); + _log_err(pamh, LOG_DEBUG, "user %s has null SMB password", name); if (off( SMB__NONULL, ctrl ) && (pdb_get_acct_ctrl(sampass) & ACB_PWNOTREQ)) @@ -335,7 +360,7 @@ int _smb_verify_password( pam_handle_t * pamh, struct samu *sampass, const char *service; _pam_get_item( pamh, PAM_SERVICE, &service ); - _log_err( LOG_NOTICE, "failed auth request by %s for service %s as %s", + _log_err(pamh, LOG_NOTICE, "failed auth request by %s for service %s as %s", uidtoname(getuid()), service ? service : "**unknown**", name); return PAM_AUTH_ERR; } @@ -343,7 +368,7 @@ int _smb_verify_password( pam_handle_t * pamh, struct samu *sampass, data_name = SMB_MALLOC_ARRAY(char, sizeof(FAIL_PREFIX) + strlen( name )); if (data_name == NULL) { - _log_err( LOG_CRIT, "no memory for data-name" ); + _log_err(pamh, LOG_CRIT, "no memory for data-name" ); return PAM_AUTH_ERR; } strncpy( data_name, FAIL_PREFIX, sizeof(FAIL_PREFIX) ); @@ -390,31 +415,31 @@ int _smb_verify_password( pam_handle_t * pamh, struct samu *sampass, retval = PAM_MAXTRIES; } } else { - _log_err(LOG_NOTICE, + _log_err(pamh, LOG_NOTICE, "failed auth request by %s for service %s as %s", uidtoname(getuid()), service ? service : "**unknown**", name); newauth->count = 1; } if (!sid_to_uid(pdb_get_user_sid(sampass), &(newauth->id))) { - _log_err(LOG_NOTICE, + _log_err(pamh, LOG_NOTICE, "failed auth request by %s for service %s as %s", uidtoname(getuid()), service ? service : "**unknown**", name); } - newauth->user = smbpXstrDup( name ); - newauth->agent = smbpXstrDup( uidtoname( getuid() ) ); + newauth->user = smbpXstrDup( pamh, name ); + newauth->agent = smbpXstrDup( pamh, uidtoname( getuid() ) ); pam_set_data( pamh, data_name, newauth, _cleanup_failures ); } else { - _log_err( LOG_CRIT, "no memory for failure recorder" ); - _log_err(LOG_NOTICE, + _log_err(pamh, LOG_CRIT, "no memory for failure recorder" ); + _log_err(pamh, LOG_NOTICE, "failed auth request by %s for service %s as %s(%d)", uidtoname(getuid()), service ? service : "**unknown**", name); } } - _log_err(LOG_NOTICE, + _log_err(pamh, LOG_NOTICE, "failed auth request by %s for service %s as %s(%d)", uidtoname(getuid()), service ? service : "**unknown**", name); @@ -422,7 +447,7 @@ int _smb_verify_password( pam_handle_t * pamh, struct samu *sampass, } _pam_delete( data_name ); - + return retval; } @@ -490,8 +515,8 @@ int _smb_read_password( pam_handle_t * pamh, unsigned int ctrl, retval = _pam_get_item( pamh, authtok_flag, &item ); if (retval != PAM_SUCCESS) { /* very strange. */ - _log_err( LOG_ALERT - , "pam_get_item returned error to smb_read_password" ); + _log_err(pamh, LOG_ALERT, + "pam_get_item returned error to smb_read_password"); return retval; } else if (item != NULL) { /* we have a password! */ *pass = item; @@ -543,7 +568,7 @@ int _smb_read_password( pam_handle_t * pamh, unsigned int ctrl, if (retval == PAM_SUCCESS) { /* a good conversation */ - token = smbpXstrDup(resp[j++].resp); + token = smbpXstrDup(pamh, resp[j++].resp); if (token != NULL) { if (expect == 2) { /* verify that password entered correctly */ @@ -555,7 +580,8 @@ int _smb_read_password( pam_handle_t * pamh, unsigned int ctrl, } } } else { - _log_err(LOG_NOTICE, "could not recover authentication token"); + _log_err(pamh, LOG_NOTICE, + "could not recover authentication token"); } } @@ -568,7 +594,7 @@ int _smb_read_password( pam_handle_t * pamh, unsigned int ctrl, if (retval != PAM_SUCCESS) { if (on( SMB_DEBUG, ctrl )) - _log_err( LOG_DEBUG, "unable to obtain a password" ); + _log_err(pamh, LOG_DEBUG, "unable to obtain a password"); return retval; } /* 'token' is the entered password */ @@ -583,7 +609,7 @@ int _smb_read_password( pam_handle_t * pamh, unsigned int ctrl, || (retval = _pam_get_item( pamh, authtok_flag ,&item )) != PAM_SUCCESS) { - _log_err( LOG_CRIT, "error manipulating password" ); + _log_err(pamh, LOG_CRIT, "error manipulating password"); return retval; } } else { @@ -597,8 +623,8 @@ int _smb_read_password( pam_handle_t * pamh, unsigned int ctrl, || (retval = _pam_get_data( pamh, data_name, &item )) != PAM_SUCCESS) { - _log_err( LOG_CRIT, "error manipulating password data [%s]" - , pam_strerror( pamh, retval )); + _log_err(pamh, LOG_CRIT, "error manipulating password data [%s]", + pam_strerror( pamh, retval )); _pam_delete( token ); item = NULL; return retval; @@ -622,8 +648,8 @@ int _pam_smb_approve_pass(pam_handle_t * pamh, if (pass_new == NULL || (pass_old && !strcmp( pass_old, pass_new ))) { if (on(SMB_DEBUG, ctrl)) { - _log_err( LOG_DEBUG, - "passwd: bad authentication token (null or unchanged)" ); + _log_err(pamh, LOG_DEBUG, + "passwd: bad authentication token (null or unchanged)"); } make_remark( pamh, ctrl, PAM_ERROR_MSG, pass_new == NULL ? "No password supplied" : "Password unchanged" ); diff --git a/source3/pam_smbpass/support.h b/source3/pam_smbpass/support.h index 87f1690a60..7ee77042d7 100644 --- a/source3/pam_smbpass/support.h +++ b/source3/pam_smbpass/support.h @@ -1,8 +1,8 @@ /* syslogging function for errors and other information */ -extern void _log_err(int, const char *, ...); +extern void _log_err(pam_handle_t *, int, const char *, ...); /* set the control flags for the UNIX module. */ -extern int set_ctrl(int, int, const char **); +extern int set_ctrl(pam_handle_t *, int, int, const char **); /* generic function for freeing pam data segments */ extern void _cleanup(pam_handle_t *, void *, int); @@ -12,7 +12,7 @@ extern void _cleanup(pam_handle_t *, void *, int); * evidence of old token around for later stack analysis. */ -extern char *smbpXstrDup(const char *); +extern char *smbpXstrDup(pam_handle_t *,const char *); /* ************************************************************** * * Useful non-trivial functions * -- cgit From 52f2f9449f8d53aa9181d656a4b54a007c80fa81 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 26 May 2009 15:30:39 +0200 Subject: s3:smbd: remove unused global 'orig_inbuf' metze --- source3/smbd/globals.c | 1 - source3/smbd/globals.h | 1 - 2 files changed, 2 deletions(-) diff --git a/source3/smbd/globals.c b/source3/smbd/globals.c index 9e7d103562..3dc057e18d 100644 --- a/source3/smbd/globals.c +++ b/source3/smbd/globals.c @@ -127,7 +127,6 @@ int max_send = BUFFER_SIZE; int max_recv = BUFFER_SIZE; uint16 last_session_tag = UID_FIELD_INVALID; int trans_num = 0; -char *orig_inbuf = NULL; pid_t mypid = 0; time_t last_smb_conf_reload_time = 0; time_t last_printer_reload_time = 0; diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index fb733355d7..2f9f7afd65 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -125,7 +125,6 @@ extern int max_send; extern int max_recv; extern uint16 last_session_tag; extern int trans_num; -extern char *orig_inbuf; extern pid_t mypid; extern time_t last_smb_conf_reload_time; -- cgit From 49ca690b4b22ee6e597179059c9442e94c5bd423 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 14 May 2009 15:34:42 +0200 Subject: Introduce "struct stat_ex" as a replacement for SMB_STRUCT_STAT This patch introduces struct stat_ex { dev_t st_ex_dev; ino_t st_ex_ino; mode_t st_ex_mode; nlink_t st_ex_nlink; uid_t st_ex_uid; gid_t st_ex_gid; dev_t st_ex_rdev; off_t st_ex_size; struct timespec st_ex_atime; struct timespec st_ex_mtime; struct timespec st_ex_ctime; struct timespec st_ex_btime; /* birthtime */ blksize_t st_ex_blksize; blkcnt_t st_ex_blocks; }; typedef struct stat_ex SMB_STRUCT_STAT; It is really large because due to the friendly libc headers playing macro tricks with fields like st_ino, so I renamed them to st_ex_xxx. Why this change? To support birthtime, we already have quite a few #ifdef's at places where it does not really belong. With a stat struct that we control, we can consolidate the nanosecond timestamps and the birthtime deep in the VFS stat calls. At this moment it is triggered by a request to support the birthtime field for GPFS. GPFS does not extend the system level struct stat, but instead has a separate call that gets us the additional information beyond posix. Without being able to do that within the VFS stat calls, that support would have to be scattered around the main smbd code. It will very likely break all the onefs modules, but I think the changes will be reasonably easy to do. --- source3/client/client.c | 42 ++++--- source3/client/clitar.c | 5 +- source3/include/includes.h | 33 +++-- source3/include/proto.h | 11 +- source3/include/smb_macros.h | 6 +- source3/lib/debug.c | 2 +- source3/lib/system.c | 225 +++++++++++++++++++++++++++++++-- source3/lib/time.c | 245 ------------------------------------ source3/lib/util.c | 10 +- source3/libsmb/clifile.c | 28 ++--- source3/libsmb/clirap.c | 6 +- source3/libsmb/libsmb_stat.c | 12 +- source3/modules/nfs4_acls.c | 11 +- source3/modules/vfs_acl_tdb.c | 4 +- source3/modules/vfs_acl_xattr.c | 4 +- source3/modules/vfs_afsacl.c | 6 +- source3/modules/vfs_commit.c | 2 +- source3/modules/vfs_default.c | 44 +++---- source3/modules/vfs_fake_perms.c | 20 +-- source3/modules/vfs_fileid.c | 4 +- source3/modules/vfs_gpfs.c | 4 +- source3/modules/vfs_hpuxacl.c | 2 +- source3/modules/vfs_netatalk.c | 12 +- source3/modules/vfs_recycle.c | 8 +- source3/modules/vfs_shadow_copy2.c | 2 +- source3/modules/vfs_streams_depot.c | 10 +- source3/modules/vfs_streams_xattr.c | 54 ++++---- source3/modules/vfs_tsmsm.c | 15 ++- source3/param/loadparm.c | 64 +++++----- source3/passdb/pdb_smbpasswd.c | 2 +- source3/printing/nt_printing.c | 4 +- source3/printing/printfsp.c | 2 +- source3/printing/printing.c | 2 +- source3/registry/regfio.c | 4 +- source3/smbd/close.c | 2 +- source3/smbd/dir.c | 12 +- source3/smbd/dosmode.c | 42 +++---- source3/smbd/file_access.c | 14 +-- source3/smbd/fileio.c | 2 +- source3/smbd/filename.c | 2 +- source3/smbd/msdfs.c | 2 +- source3/smbd/nttrans.c | 28 ++--- source3/smbd/open.c | 56 ++++----- source3/smbd/posix_acls.c | 58 ++++----- source3/smbd/reply.c | 67 +++++----- source3/smbd/service.c | 4 +- source3/smbd/trans2.c | 104 +++++++-------- source3/smbd/vfs.c | 28 ++--- source3/torture/cmd_vfs.c | 180 ++++++++++++++------------ source3/utils/net_conf.c | 2 +- source3/utils/net_usershare.c | 14 +-- source3/utils/testparm.c | 6 +- source3/web/cgi.c | 8 +- 53 files changed, 768 insertions(+), 768 deletions(-) diff --git a/source3/client/client.c b/source3/client/client.c index 59e5c1ad72..13dee6081d 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -3022,7 +3022,7 @@ static int cmd_getfacl(void) } d_printf("# file: %s\n", src); - d_printf("# owner: %u\n# group: %u\n", (unsigned int)sbuf.st_uid, (unsigned int)sbuf.st_gid); + d_printf("# owner: %u\n# group: %u\n", (unsigned int)sbuf.st_ex_uid, (unsigned int)sbuf.st_ex_gid); if (num_file_acls == 0 && num_dir_acls == 0) { d_printf("No acls found.\n"); @@ -3120,6 +3120,7 @@ static int cmd_stat(void) fstring mode_str; SMB_STRUCT_STAT sbuf; struct tm *lt; + time_t tmp_time; if (!next_token_talloc(ctx, &cmd_ptr,&name,NULL)) { d_printf("stat file\n"); @@ -3152,30 +3153,31 @@ static int cmd_stat(void) /* Print out the stat values. */ d_printf("File: %s\n", src); d_printf("Size: %-12.0f\tBlocks: %u\t%s\n", - (double)sbuf.st_size, - (unsigned int)sbuf.st_blocks, - filetype_to_str(sbuf.st_mode)); + (double)sbuf.st_ex_size, + (unsigned int)sbuf.st_ex_blocks, + filetype_to_str(sbuf.st_ex_mode)); #if defined(S_ISCHR) && defined(S_ISBLK) - if (S_ISCHR(sbuf.st_mode) || S_ISBLK(sbuf.st_mode)) { + if (S_ISCHR(sbuf.st_ex_mode) || S_ISBLK(sbuf.st_ex_mode)) { d_printf("Inode: %.0f\tLinks: %u\tDevice type: %u,%u\n", - (double)sbuf.st_ino, - (unsigned int)sbuf.st_nlink, - unix_dev_major(sbuf.st_rdev), - unix_dev_minor(sbuf.st_rdev)); + (double)sbuf.st_ex_ino, + (unsigned int)sbuf.st_ex_nlink, + unix_dev_major(sbuf.st_ex_rdev), + unix_dev_minor(sbuf.st_ex_rdev)); } else #endif d_printf("Inode: %.0f\tLinks: %u\n", - (double)sbuf.st_ino, - (unsigned int)sbuf.st_nlink); + (double)sbuf.st_ex_ino, + (unsigned int)sbuf.st_ex_nlink); d_printf("Access: (0%03o/%s)\tUid: %u\tGid: %u\n", - ((int)sbuf.st_mode & 0777), - unix_mode_to_str(mode_str, sbuf.st_mode), - (unsigned int)sbuf.st_uid, - (unsigned int)sbuf.st_gid); + ((int)sbuf.st_ex_mode & 0777), + unix_mode_to_str(mode_str, sbuf.st_ex_mode), + (unsigned int)sbuf.st_ex_uid, + (unsigned int)sbuf.st_ex_gid); - lt = localtime(&sbuf.st_atime); + tmp_time = convert_timespec_to_time_t(sbuf.st_ex_atime); + lt = localtime(&tmp_time); if (lt) { strftime(mode_str, sizeof(mode_str), "%Y-%m-%d %T %z", lt); } else { @@ -3183,7 +3185,8 @@ static int cmd_stat(void) } d_printf("Access: %s\n", mode_str); - lt = localtime(&sbuf.st_mtime); + tmp_time = convert_timespec_to_time_t(sbuf.st_ex_mtime); + lt = localtime(&tmp_time); if (lt) { strftime(mode_str, sizeof(mode_str), "%Y-%m-%d %T %z", lt); } else { @@ -3191,7 +3194,8 @@ static int cmd_stat(void) } d_printf("Modify: %s\n", mode_str); - lt = localtime(&sbuf.st_ctime); + tmp_time = convert_timespec_to_time_t(sbuf.st_ex_ctime); + lt = localtime(&tmp_time); if (lt) { strftime(mode_str, sizeof(mode_str), "%Y-%m-%d %T %z", lt); } else { @@ -3400,7 +3404,7 @@ static int cmd_newer(void) ok = next_token_talloc(ctx, &cmd_ptr,&buf,NULL); if (ok && (sys_stat(buf,&sbuf) == 0)) { - newer_than = sbuf.st_mtime; + newer_than = convert_timespec_to_time_t(sbuf.st_ex_mtime); DEBUG(1,("Getting files newer than %s", time_to_asc(newer_than))); } else { diff --git a/source3/client/clitar.c b/source3/client/clitar.c index ff71924555..d973329427 100644 --- a/source3/client/clitar.c +++ b/source3/client/clitar.c @@ -412,7 +412,7 @@ static void dotareof(int f) /* Could be a pipe, in which case S_ISREG should fail, * and we should write out at full size */ if (tp > 0) { - size_t towrite = S_ISREG(stbuf.st_mode) ? tp : tbufsiz; + size_t towrite = S_ISREG(stbuf.st_ex_mode) ? tp : tbufsiz; if (sys_write(f, tarbuf, towrite) != towrite) { DEBUG(0,("dotareof: sys_write fail\n")); } @@ -1793,7 +1793,8 @@ int tar_parseargs(int argc, char *argv[], const char *Optarg, int Optind) SMB_STRUCT_STAT stbuf; if (sys_stat(argv[Optind], &stbuf) == 0) { - newer_than = stbuf.st_mtime; + newer_than = convert_timespec_to_time_t( + stbuf.st_ex_mtime); DEBUG(1,("Getting files newer than %s", time_to_asc(newer_than))); newOptind++; diff --git a/source3/include/includes.h b/source3/include/includes.h index 596c772d9e..a2f6048c27 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -435,13 +435,32 @@ typedef uint64_t br_off; * Type for stat structure. */ -#ifndef SMB_STRUCT_STAT -# if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_STAT64) && defined(HAVE_OFF64_T) -# define SMB_STRUCT_STAT struct stat64 -# else -# define SMB_STRUCT_STAT struct stat -# endif -#endif +struct stat_ex { + dev_t st_ex_dev; + ino_t st_ex_ino; + mode_t st_ex_mode; + nlink_t st_ex_nlink; + uid_t st_ex_uid; + gid_t st_ex_gid; + dev_t st_ex_rdev; + off_t st_ex_size; + struct timespec st_ex_atime; + struct timespec st_ex_mtime; + struct timespec st_ex_ctime; + struct timespec st_ex_btime; /* birthtime */ + blksize_t st_ex_blksize; + blkcnt_t st_ex_blocks; + + /* + * Add space for VFS internal extensions. The initial user of this + * would be the onefs modules, passing the snapid from the stat calls + * to the file_id_create call. Maybe we'll have to expand this later, + * but the core of Samba should never look at this field. + */ + uint64_t vfs_private; +}; + +typedef struct stat_ex SMB_STRUCT_STAT; /* * Type for dirent structure. diff --git a/source3/include/proto.h b/source3/include/proto.h index e0b0e59700..c78d2c8e0b 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1010,13 +1010,6 @@ void srv_put_dos_date2(char *buf,int offset, time_t unixdate); void srv_put_dos_date3(char *buf,int offset,time_t unixdate); void put_long_date_timespec(char *p, struct timespec ts); void put_long_date(char *p, time_t t); -struct timespec get_create_timespec(const SMB_STRUCT_STAT *st,bool fake_dirs); -struct timespec get_atimespec(const SMB_STRUCT_STAT *pst); -void set_atimespec(SMB_STRUCT_STAT *pst, struct timespec ts); -struct timespec get_mtimespec(const SMB_STRUCT_STAT *pst); -void set_mtimespec(SMB_STRUCT_STAT *pst, struct timespec ts); -struct timespec get_ctimespec(const SMB_STRUCT_STAT *pst); -void set_ctimespec(SMB_STRUCT_STAT *pst, struct timespec ts); void dos_filetime_timespec(struct timespec *tsp); time_t make_unix_date2(const void *date_ptr, int zone_offset); time_t make_unix_date3(const void *date_ptr, int zone_offset); @@ -4087,7 +4080,7 @@ bool lp_recursive_veto_delete(int ); bool lp_dos_filemode(int ); bool lp_dos_filetimes(int ); bool lp_dos_filetime_resolution(int ); -bool lp_fake_dir_create_times(int ); +bool lp_fake_dir_create_times(void); bool lp_blocking_locks(int ); bool lp_inherit_perms(int ); bool lp_inherit_acls(int ); @@ -6174,7 +6167,7 @@ bool get_dir_entry(TALLOC_CTX *ctx, char **pp_fname_out, SMB_OFF_T *size, uint32 *mode, - time_t *date, + struct timespec *date, bool check_descend, bool ask_sharemode); bool is_visible_file(connection_struct *conn, const char *dir_path, const char *name, SMB_STRUCT_STAT *pst, bool use_veto); diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h index 22cfaaf581..7528883c2d 100644 --- a/source3/include/smb_macros.h +++ b/source3/include/smb_macros.h @@ -88,9 +88,9 @@ * stat structure is valid. */ -#define VALID_STAT(st) ((st).st_nlink != 0) -#define VALID_STAT_OF_DIR(st) (VALID_STAT(st) && S_ISDIR((st).st_mode)) -#define SET_STAT_INVALID(st) ((st).st_nlink = 0) +#define VALID_STAT(st) ((st).st_ex_nlink != 0) +#define VALID_STAT_OF_DIR(st) (VALID_STAT(st) && S_ISDIR((st).st_ex_mode)) +#define SET_STAT_INVALID(st) ((st).st_ex_nlink = 0) /* Macros to get at offsets within smb_lkrng and smb_unlkrng structures. We cannot define these as actual structures diff --git a/source3/lib/debug.c b/source3/lib/debug.c index 14aca3adad..419af61ef3 100644 --- a/source3/lib/debug.c +++ b/source3/lib/debug.c @@ -739,7 +739,7 @@ void check_log_size( void ) maxlog = lp_max_log_size() * 1024; - if( sys_fstat( x_fileno( dbf ), &st ) == 0 && st.st_size > maxlog ) { + if( sys_fstat( x_fileno( dbf ), &st ) == 0 && st.st_ex_size > maxlog ) { (void)reopen_logs(); if( dbf && get_file_size( debugf ) > maxlog ) { char *name = NULL; diff --git a/source3/lib/system.c b/source3/lib/system.c index 517e347c0f..5158750f98 100644 --- a/source3/lib/system.c +++ b/source3/lib/system.c @@ -290,6 +290,195 @@ int sys_fcntl_long(int fd, int cmd, long arg) return ret; } +/**************************************************************************** + Return the best approximation to a 'create time' under UNIX from a stat + structure. +****************************************************************************/ + +static time_t calc_create_time(const struct stat *st) +{ + time_t ret, ret1; + + ret = MIN(st->st_ctime, st->st_mtime); + ret1 = MIN(ret, st->st_atime); + + if(ret1 != (time_t)0) { + return ret1; + } + + /* + * One of ctime, mtime or atime was zero (probably atime). + * Just return MIN(ctime, mtime). + */ + return ret; +} + +/**************************************************************************** + Return the 'create time' from a stat struct if it exists (birthtime) or else + use the best approximation. +****************************************************************************/ + +static struct timespec get_create_timespec(const struct stat *pst) +{ + struct timespec ret; + + if (S_ISDIR(pst->st_mode) && lp_fake_dir_create_times()) { + ret.tv_sec = 315493200L; /* 1/1/1980 */ + ret.tv_nsec = 0; + return ret; + } + +#if defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC) + ret = pst->st_birthtimespec; +#elif defined(HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC) + ret.tv_sec = pst->st_birthtime; + ret.tv_nsec = pst->st_birthtimenspec; +#elif defined(HAVE_STRUCT_STAT_ST_BIRTHTIME) + ret.tv_sec = pst->st_birthtime; + ret.tv_nsec = 0; +#else + ret.tv_sec = calc_create_time(pst); + ret.tv_nsec = 0; +#endif + + /* Deal with systems that don't initialize birthtime correctly. + * Pointed out by SATOH Fumiyasu . + */ + if (null_timespec(ret)) { + ret.tv_sec = calc_create_time(pst); + ret.tv_nsec = 0; + } + return ret; +} + +/**************************************************************************** + Get/Set all the possible time fields from a stat struct as a timespec. +****************************************************************************/ + +static struct timespec get_atimespec(const struct stat *pst) +{ +#if !defined(HAVE_STAT_HIRES_TIMESTAMPS) + struct timespec ret; + + /* Old system - no ns timestamp. */ + ret.tv_sec = pst->st_atime; + ret.tv_nsec = 0; + return ret; +#else +#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) + return pst->st_atim; +#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC) + struct timespec ret; + ret.tv_sec = pst->st_atime; + ret.tv_nsec = pst->st_atimensec; + return ret; +#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N) + struct timespec ret; + ret.tv_sec = pst->st_atime; + ret.tv_nsec = pst->st_atime_n; + return ret; +#elif defined(HAVE_STRUCT_STAT_ST_UMTIME) + struct timespec ret; + ret.tv_sec = pst->st_atime; + ret.tv_nsec = pst->st_uatime * 1000; + return ret; +#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC) + return pst->st_atimespec; +#else +#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT +#endif +#endif +} + +static struct timespec get_mtimespec(const struct stat *pst) +{ +#if !defined(HAVE_STAT_HIRES_TIMESTAMPS) + struct timespec ret; + + /* Old system - no ns timestamp. */ + ret.tv_sec = pst->st_mtime; + ret.tv_nsec = 0; + return ret; +#else +#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) + return pst->st_mtim; +#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC) + struct timespec ret; + ret.tv_sec = pst->st_mtime; + ret.tv_nsec = pst->st_mtimensec; + return ret; +#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N) + struct timespec ret; + ret.tv_sec = pst->st_mtime; + ret.tv_nsec = pst->st_mtime_n; + return ret; +#elif defined(HAVE_STRUCT_STAT_ST_UMTIME) + struct timespec ret; + ret.tv_sec = pst->st_mtime; + ret.tv_nsec = pst->st_umtime * 1000; + return ret; +#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC) + return pst->st_mtimespec; +#else +#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT +#endif +#endif +} + +static struct timespec get_ctimespec(const struct stat *pst) +{ +#if !defined(HAVE_STAT_HIRES_TIMESTAMPS) + struct timespec ret; + + /* Old system - no ns timestamp. */ + ret.tv_sec = pst->st_ctime; + ret.tv_nsec = 0; + return ret; +#else +#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) + return pst->st_ctim; +#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC) + struct timespec ret; + ret.tv_sec = pst->st_ctime; + ret.tv_nsec = pst->st_ctimensec; + return ret; +#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N) + struct timespec ret; + ret.tv_sec = pst->st_ctime; + ret.tv_nsec = pst->st_ctime_n; + return ret; +#elif defined(HAVE_STRUCT_STAT_ST_UMTIME) + struct timespec ret; + ret.tv_sec = pst->st_ctime; + ret.tv_nsec = pst->st_uctime * 1000; + return ret; +#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC) + return pst->st_ctimespec; +#else +#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT +#endif +#endif +} + +static void init_stat_ex_from_stat (struct stat_ex *dst, + const struct stat *src) +{ + dst->st_ex_dev = src->st_dev; + dst->st_ex_ino = src->st_ino; + dst->st_ex_mode = src->st_mode; + dst->st_ex_nlink = src->st_nlink; + dst->st_ex_uid = src->st_uid; + dst->st_ex_gid = src->st_gid; + dst->st_ex_rdev = src->st_rdev; + dst->st_ex_size = src->st_size; + dst->st_ex_atime = get_atimespec(src); + dst->st_ex_mtime = get_mtimespec(src); + dst->st_ex_ctime = get_ctimespec(src); + dst->st_ex_btime = get_create_timespec(src); + dst->st_ex_blksize = src->st_blksize; + dst->st_ex_blocks = src->st_blocks; +} + /******************************************************************* A stat() wrapper that will deal with 64 bit filesizes. ********************************************************************/ @@ -300,10 +489,16 @@ int sys_stat(const char *fname,SMB_STRUCT_STAT *sbuf) #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_STAT64) ret = stat64(fname, sbuf); #else - ret = stat(fname, sbuf); + struct stat statbuf; + ret = stat(fname, &statbuf); #endif - /* we always want directories to appear zero size */ - if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0; + if (ret == 0) { + /* we always want directories to appear zero size */ + if (S_ISDIR(statbuf.st_mode)) { + statbuf.st_size = 0; + } + init_stat_ex_from_stat(sbuf, &statbuf); + } return ret; } @@ -317,10 +512,16 @@ int sys_fstat(int fd,SMB_STRUCT_STAT *sbuf) #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64) ret = fstat64(fd, sbuf); #else - ret = fstat(fd, sbuf); + struct stat statbuf; + ret = fstat(fd, &statbuf); #endif - /* we always want directories to appear zero size */ - if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0; + if (ret == 0) { + /* we always want directories to appear zero size */ + if (S_ISDIR(statbuf.st_mode)) { + statbuf.st_size = 0; + } + init_stat_ex_from_stat(sbuf, &statbuf); + } return ret; } @@ -334,10 +535,16 @@ int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf) #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64) ret = lstat64(fname, sbuf); #else - ret = lstat(fname, sbuf); + struct stat statbuf; + ret = lstat(fname, &statbuf); #endif - /* we always want directories to appear zero size */ - if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0; + if (ret == 0) { + /* we always want directories to appear zero size */ + if (S_ISDIR(statbuf.st_mode)) { + statbuf.st_size = 0; + } + init_stat_ex_from_stat(sbuf, &statbuf); + } return ret; } diff --git a/source3/lib/time.c b/source3/lib/time.c index 611debe366..a2e615acc5 100644 --- a/source3/lib/time.c +++ b/source3/lib/time.c @@ -322,251 +322,6 @@ void put_long_date(char *p, time_t t) put_long_date_timespec(p, ts); } -/**************************************************************************** - Return the best approximation to a 'create time' under UNIX from a stat - structure. -****************************************************************************/ - -static time_t calc_create_time(const SMB_STRUCT_STAT *st) -{ - time_t ret, ret1; - - ret = MIN(st->st_ctime, st->st_mtime); - ret1 = MIN(ret, st->st_atime); - - if(ret1 != (time_t)0) { - return ret1; - } - - /* - * One of ctime, mtime or atime was zero (probably atime). - * Just return MIN(ctime, mtime). - */ - return ret; -} - -/**************************************************************************** - Return the 'create time' from a stat struct if it exists (birthtime) or else - use the best approximation. -****************************************************************************/ - -struct timespec get_create_timespec(const SMB_STRUCT_STAT *pst,bool fake_dirs) -{ - struct timespec ret; - - if(S_ISDIR(pst->st_mode) && fake_dirs) { - ret.tv_sec = 315493200L; /* 1/1/1980 */ - ret.tv_nsec = 0; - return ret; - } - -#if defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC) - ret = pst->st_birthtimespec; -#elif defined(HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC) - ret.tv_sec = pst->st_birthtime; - ret.tv_nsec = pst->st_birthtimenspec; -#elif defined(HAVE_STRUCT_STAT_ST_BIRTHTIME) - ret.tv_sec = pst->st_birthtime; - ret.tv_nsec = 0; -#else - ret.tv_sec = calc_create_time(pst); - ret.tv_nsec = 0; -#endif - - /* Deal with systems that don't initialize birthtime correctly. - * Pointed out by SATOH Fumiyasu . - */ - if (null_timespec(ret)) { - ret.tv_sec = calc_create_time(pst); - ret.tv_nsec = 0; - } - return ret; -} - -/**************************************************************************** - Get/Set all the possible time fields from a stat struct as a timespec. -****************************************************************************/ - -struct timespec get_atimespec(const SMB_STRUCT_STAT *pst) -{ -#if !defined(HAVE_STAT_HIRES_TIMESTAMPS) - struct timespec ret; - - /* Old system - no ns timestamp. */ - ret.tv_sec = pst->st_atime; - ret.tv_nsec = 0; - return ret; -#else -#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) - return pst->st_atim; -#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC) - struct timespec ret; - ret.tv_sec = pst->st_atime; - ret.tv_nsec = pst->st_atimensec; - return ret; -#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N) - struct timespec ret; - ret.tv_sec = pst->st_atime; - ret.tv_nsec = pst->st_atime_n; - return ret; -#elif defined(HAVE_STRUCT_STAT_ST_UMTIME) - struct timespec ret; - ret.tv_sec = pst->st_atime; - ret.tv_nsec = pst->st_uatime * 1000; - return ret; -#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC) - return pst->st_atimespec; -#else -#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT -#endif -#endif -} - -void set_atimespec(SMB_STRUCT_STAT *pst, struct timespec ts) -{ -#if !defined(HAVE_STAT_HIRES_TIMESTAMPS) - /* Old system - no ns timestamp. */ - pst->st_atime = ts.tv_sec; -#else -#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) - pst->st_atim = ts; -#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC) - pst->st_atime = ts.tv_sec; - pst->st_atimensec = ts.tv_nsec; -#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N) - pst->st_atime = ts.tv_sec; - pst->st_atime_n = ts.tv_nsec; -#elif defined(HAVE_STRUCT_STAT_ST_UMTIME) - pst->st_atime = ts.tv_sec; - pst->st_uatime = ts.tv_nsec / 1000; -#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC) - pst->st_atimespec = ts; -#else -#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT -#endif -#endif -} - -struct timespec get_mtimespec(const SMB_STRUCT_STAT *pst) -{ -#if !defined(HAVE_STAT_HIRES_TIMESTAMPS) - struct timespec ret; - - /* Old system - no ns timestamp. */ - ret.tv_sec = pst->st_mtime; - ret.tv_nsec = 0; - return ret; -#else -#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) - return pst->st_mtim; -#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC) - struct timespec ret; - ret.tv_sec = pst->st_mtime; - ret.tv_nsec = pst->st_mtimensec; - return ret; -#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N) - struct timespec ret; - ret.tv_sec = pst->st_mtime; - ret.tv_nsec = pst->st_mtime_n; - return ret; -#elif defined(HAVE_STRUCT_STAT_ST_UMTIME) - struct timespec ret; - ret.tv_sec = pst->st_mtime; - ret.tv_nsec = pst->st_umtime * 1000; - return ret; -#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC) - return pst->st_mtimespec; -#else -#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT -#endif -#endif -} - -void set_mtimespec(SMB_STRUCT_STAT *pst, struct timespec ts) -{ -#if !defined(HAVE_STAT_HIRES_TIMESTAMPS) - /* Old system - no ns timestamp. */ - pst->st_mtime = ts.tv_sec; -#else -#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) - pst->st_mtim = ts; -#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC) - pst->st_mtime = ts.tv_sec; - pst->st_mtimensec = ts.tv_nsec; -#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N) - pst->st_mtime = ts.tv_sec; - pst->st_mtime_n = ts.tv_nsec; -#elif defined(HAVE_STRUCT_STAT_ST_UMTIME) - pst->st_mtime = ts.tv_sec; - pst->st_umtime = ts.tv_nsec / 1000; -#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC) - pst->st_mtimespec = ts; -#else -#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT -#endif -#endif -} - -struct timespec get_ctimespec(const SMB_STRUCT_STAT *pst) -{ -#if !defined(HAVE_STAT_HIRES_TIMESTAMPS) - struct timespec ret; - - /* Old system - no ns timestamp. */ - ret.tv_sec = pst->st_ctime; - ret.tv_nsec = 0; - return ret; -#else -#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) - return pst->st_ctim; -#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC) - struct timespec ret; - ret.tv_sec = pst->st_ctime; - ret.tv_nsec = pst->st_ctimensec; - return ret; -#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N) - struct timespec ret; - ret.tv_sec = pst->st_ctime; - ret.tv_nsec = pst->st_ctime_n; - return ret; -#elif defined(HAVE_STRUCT_STAT_ST_UMTIME) - struct timespec ret; - ret.tv_sec = pst->st_ctime; - ret.tv_nsec = pst->st_uctime * 1000; - return ret; -#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC) - return pst->st_ctimespec; -#else -#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT -#endif -#endif -} - -void set_ctimespec(SMB_STRUCT_STAT *pst, struct timespec ts) -{ -#if !defined(HAVE_STAT_HIRES_TIMESTAMPS) - /* Old system - no ns timestamp. */ - pst->st_ctime = ts.tv_sec; -#else -#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) - pst->st_ctim = ts; -#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC) - pst->st_ctime = ts.tv_sec; - pst->st_ctimensec = ts.tv_nsec; -#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N) - pst->st_ctime = ts.tv_sec; - pst->st_ctime_n = ts.tv_nsec; -#elif defined(HAVE_STRUCT_STAT_ST_UMTIME) - pst->st_ctime = ts.tv_sec; - pst->st_uctime = ts.tv_nsec / 1000; -#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC) - pst->st_ctimespec = ts; -#else -#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT -#endif -#endif -} - void dos_filetime_timespec(struct timespec *tsp) { tsp->tv_sec &= ~1; diff --git a/source3/lib/util.c b/source3/lib/util.c index c86f259ce3..13f7e3c9ee 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -541,7 +541,7 @@ bool file_exist_stat(const char *fname,SMB_STRUCT_STAT *sbuf) if (sys_stat(fname,sbuf) != 0) return(False); - return((S_ISREG(sbuf->st_mode)) || (S_ISFIFO(sbuf->st_mode))); + return((S_ISREG(sbuf->st_ex_mode)) || (S_ISFIFO(sbuf->st_ex_mode))); } /******************************************************************* @@ -554,7 +554,7 @@ bool socket_exist(const char *fname) if (sys_stat(fname,&st) != 0) return(False); - return S_ISSOCK(st.st_mode); + return S_ISSOCK(st.st_ex_mode); } /******************************************************************* @@ -572,7 +572,7 @@ bool directory_exist_stat(char *dname,SMB_STRUCT_STAT *st) if (sys_stat(dname,st) != 0) return(False); - ret = S_ISDIR(st->st_mode); + ret = S_ISDIR(st->st_ex_mode); if(!ret) errno = ENOTDIR; return ret; @@ -584,7 +584,7 @@ bool directory_exist_stat(char *dname,SMB_STRUCT_STAT *st) uint64_t get_file_size_stat(const SMB_STRUCT_STAT *sbuf) { - return sbuf->st_size; + return sbuf->st_ex_size; } /******************************************************************* @@ -594,7 +594,7 @@ uint64_t get_file_size_stat(const SMB_STRUCT_STAT *sbuf) SMB_OFF_T get_file_size(char *file_name) { SMB_STRUCT_STAT buf; - buf.st_size = 0; + buf.st_ex_size = 0; if(sys_stat(file_name,&buf) != 0) return (SMB_OFF_T)-1; return get_file_size_stat(&buf); diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 2c80f1dd1a..1225aa6bae 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -294,31 +294,31 @@ bool cli_unix_stat(struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbu return false; } - sbuf->st_size = IVAL2_TO_SMB_BIG_UINT(rdata,0); /* total size, in bytes */ - sbuf->st_blocks = IVAL2_TO_SMB_BIG_UINT(rdata,8); /* number of blocks allocated */ + sbuf->st_ex_size = IVAL2_TO_SMB_BIG_UINT(rdata,0); /* total size, in bytes */ + sbuf->st_ex_blocks = IVAL2_TO_SMB_BIG_UINT(rdata,8); /* number of blocks allocated */ #if defined (HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE) - sbuf->st_blocks /= STAT_ST_BLOCKSIZE; + sbuf->st_ex_blocks /= STAT_ST_BLOCKSIZE; #else /* assume 512 byte blocks */ - sbuf->st_blocks /= 512; + sbuf->st_ex_blocks /= 512; #endif - set_ctimespec(sbuf, interpret_long_date(rdata + 16)); /* time of last change */ - set_atimespec(sbuf, interpret_long_date(rdata + 24)); /* time of last access */ - set_mtimespec(sbuf, interpret_long_date(rdata + 32)); /* time of last modification */ + sbuf->st_ex_ctime = interpret_long_date(rdata + 16); /* time of last change */ + sbuf->st_ex_atime = interpret_long_date(rdata + 24); /* time of last access */ + sbuf->st_ex_mtime = interpret_long_date(rdata + 32); /* time of last modification */ - sbuf->st_uid = (uid_t) IVAL(rdata,40); /* user ID of owner */ - sbuf->st_gid = (gid_t) IVAL(rdata,48); /* group ID of owner */ - sbuf->st_mode |= unix_filetype_from_wire(IVAL(rdata, 56)); + sbuf->st_ex_uid = (uid_t) IVAL(rdata,40); /* user ID of owner */ + sbuf->st_ex_gid = (gid_t) IVAL(rdata,48); /* group ID of owner */ + sbuf->st_ex_mode |= unix_filetype_from_wire(IVAL(rdata, 56)); #if defined(HAVE_MAKEDEV) { uint32_t dev_major = IVAL(rdata,60); uint32_t dev_minor = IVAL(rdata,68); - sbuf->st_rdev = makedev(dev_major, dev_minor); + sbuf->st_ex_rdev = makedev(dev_major, dev_minor); } #endif - sbuf->st_ino = (SMB_INO_T)IVAL2_TO_SMB_BIG_UINT(rdata,76); /* inode */ - sbuf->st_mode |= wire_perms_to_unix(IVAL(rdata,84)); /* protection */ - sbuf->st_nlink = IVAL(rdata,92); /* number of hard links */ + sbuf->st_ex_ino = (SMB_INO_T)IVAL2_TO_SMB_BIG_UINT(rdata,76); /* inode */ + sbuf->st_ex_mode |= wire_perms_to_unix(IVAL(rdata,84)); /* protection */ + sbuf->st_ex_nlink = IVAL(rdata,92); /* number of hard links */ SAFE_FREE(rdata); SAFE_FREE(rparam); diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 1771e8fd25..c3ec82bd3e 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -1105,9 +1105,9 @@ bool cli_qpathinfo_basic( struct cli_state *cli, const char *name, return False; } - set_atimespec(sbuf, interpret_long_date( rdata+8 )); /* Access time. */ - set_mtimespec(sbuf, interpret_long_date( rdata+16 )); /* Write time. */ - set_ctimespec(sbuf, interpret_long_date( rdata+24 )); /* Change time. */ + sbuf->st_ex_atime = interpret_long_date( rdata+8 ); /* Access time. */ + sbuf->st_ex_mtime = interpret_long_date( rdata+16 ); /* Write time. */ + sbuf->st_ex_ctime = interpret_long_date( rdata+24 ); /* Change time. */ *attributes = IVAL( rdata, 32 ); diff --git a/source3/libsmb/libsmb_stat.c b/source3/libsmb/libsmb_stat.c index af7800ba32..4349b0a700 100644 --- a/source3/libsmb/libsmb_stat.c +++ b/source3/libsmb/libsmb_stat.c @@ -188,9 +188,9 @@ SMBC_stat_ctx(SMBCCTX *context, setup_stat(context, st, (char *) fname, size, mode); - set_atimespec(st, access_time_ts); - set_ctimespec(st, change_time_ts); - set_mtimespec(st, write_time_ts); + st->st_atime = convert_timespec_to_time_t(access_time_ts); + st->st_ctime = convert_timespec_to_time_t(change_time_ts); + st->st_mtime = convert_timespec_to_time_t(write_time_ts); st->st_dev = srv->dev; TALLOC_FREE(frame); @@ -293,9 +293,9 @@ SMBC_fstat_ctx(SMBCCTX *context, setup_stat(context, st, file->fname, size, mode); - set_atimespec(st, access_time_ts); - set_ctimespec(st, change_time_ts); - set_mtimespec(st, write_time_ts); + st->st_atime = convert_timespec_to_time_t(access_time_ts); + st->st_ctime = convert_timespec_to_time_t(change_time_ts); + st->st_mtime = convert_timespec_to_time_t(write_time_ts); st->st_dev = file->srv->dev; TALLOC_FREE(frame); diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c index 462e59313a..04ea73f45e 100644 --- a/source3/modules/nfs4_acls.c +++ b/source3/modules/nfs4_acls.c @@ -289,10 +289,11 @@ static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf, * shouldn't alloc 0 for * win */ - uid_to_sid(&sid_owner, sbuf->st_uid); - gid_to_sid(&sid_group, sbuf->st_gid); + uid_to_sid(&sid_owner, sbuf->st_ex_uid); + gid_to_sid(&sid_group, sbuf->st_ex_gid); - if (smbacl4_nfs42win(mem_ctx, theacl, &sid_owner, &sid_group, S_ISDIR(sbuf->st_mode), + if (smbacl4_nfs42win(mem_ctx, theacl, &sid_owner, &sid_group, + S_ISDIR(sbuf->st_ex_mode), &nt_ace_list, &good_aces)==False) { DEBUG(8,("smbacl4_nfs42win failed\n")); return map_nt_error_from_unix(errno); @@ -733,8 +734,8 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp, DEBUG(8, ("unpack_nt_owners failed")); return status; } - if (((newUID != (uid_t)-1) && (sbuf.st_uid != newUID)) || - ((newGID != (gid_t)-1) && (sbuf.st_gid != newGID))) { + if (((newUID != (uid_t)-1) && (sbuf.st_ex_uid != newUID)) || + ((newGID != (gid_t)-1) && (sbuf.st_ex_gid != newGID))) { if(try_chown(fsp->conn, fsp->fsp_name, newUID, newGID)) { DEBUG(3,("chown %s, %u, %u failed. Error = %s.\n", fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID, diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c index a77f6d60f4..463250a9ed 100644 --- a/source3/modules/vfs_acl_tdb.c +++ b/source3/modules/vfs_acl_tdb.c @@ -414,8 +414,8 @@ static struct security_descriptor *default_file_sd(TALLOC_CTX *mem_ctx, struct security_ace *pace = NULL; struct security_acl *pacl = NULL; - uid_to_sid(&owner_sid, psbuf->st_uid); - gid_to_sid(&group_sid, psbuf->st_gid); + uid_to_sid(&owner_sid, psbuf->st_ex_uid); + gid_to_sid(&group_sid, psbuf->st_ex_gid); pace = TALLOC_ARRAY(mem_ctx, struct security_ace, 2); if (!pace) { diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c index 49e4899879..05156f8456 100644 --- a/source3/modules/vfs_acl_xattr.c +++ b/source3/modules/vfs_acl_xattr.c @@ -282,8 +282,8 @@ static struct security_descriptor *default_file_sd(TALLOC_CTX *mem_ctx, struct security_ace *pace = NULL; struct security_acl *pacl = NULL; - uid_to_sid(&owner_sid, psbuf->st_uid); - gid_to_sid(&group_sid, psbuf->st_gid); + uid_to_sid(&owner_sid, psbuf->st_ex_uid); + gid_to_sid(&group_sid, psbuf->st_ex_gid); pace = TALLOC_ARRAY(mem_ctx, struct security_ace, 2); if (!pace) { diff --git a/source3/modules/vfs_afsacl.c b/source3/modules/vfs_afsacl.c index 8c89d2fd9f..e537f01b03 100644 --- a/source3/modules/vfs_afsacl.c +++ b/source3/modules/vfs_afsacl.c @@ -599,8 +599,8 @@ static size_t afs_to_nt_acl_common(struct afs_acl *afs_acl, struct afs_ace *afs_ace; - uid_to_sid(&owner_sid, psbuf->st_uid); - gid_to_sid(&group_sid, psbuf->st_gid); + uid_to_sid(&owner_sid, psbuf->st_ex_uid); + gid_to_sid(&group_sid, psbuf->st_ex_gid); if (afs_acl->num_aces) { nt_ace_list = TALLOC_ARRAY(mem_ctx, SEC_ACE, afs_acl->num_aces); @@ -626,7 +626,7 @@ static size_t afs_to_nt_acl_common(struct afs_acl *afs_acl, continue; } - if (S_ISDIR(psbuf->st_mode)) + if (S_ISDIR(psbuf->st_ex_mode)) afs_to_nt_dir_rights(afs_ace->rights, &nt_rights, &flag); else diff --git a/source3/modules/vfs_commit.c b/source3/modules/vfs_commit.c index a8105e021e..c22e8161d7 100644 --- a/source3/modules/vfs_commit.c +++ b/source3/modules/vfs_commit.c @@ -220,7 +220,7 @@ static int commit_open( if (SMB_VFS_FSTAT(fsp, &st) == -1) { return -1; } - c->eof = st.st_size; + c->eof = st.st_ex_size; } return 0; diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index aa207056b3..fe63d5001a 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -430,7 +430,7 @@ static int copy_reg(const char *source, const char *dest) if (sys_lstat (source, &source_stats) == -1) return -1; - if (!S_ISREG (source_stats.st_mode)) + if (!S_ISREG (source_stats.st_ex_mode)) return -1; if((ifd = sys_open (source, O_RDONLY, 0)) < 0) @@ -455,9 +455,9 @@ static int copy_reg(const char *source, const char *dest) */ #ifdef HAVE_FCHOWN - if ((fchown(ofd, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != EPERM)) + if ((fchown(ofd, source_stats.st_ex_uid, source_stats.st_ex_gid) == -1) && (errno != EPERM)) #else - if ((chown(dest, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != EPERM)) + if ((chown(dest, source_stats.st_ex_uid, source_stats.st_ex_gid) == -1) && (errno != EPERM)) #endif goto err; @@ -467,9 +467,9 @@ static int copy_reg(const char *source, const char *dest) */ #if defined(HAVE_FCHMOD) - if (fchmod (ofd, source_stats.st_mode & 07777)) + if (fchmod (ofd, source_stats.st_ex_mode & 07777)) #else - if (chmod (dest, source_stats.st_mode & 07777)) + if (chmod (dest, source_stats.st_ex_mode & 07777)) #endif goto err; @@ -483,8 +483,8 @@ static int copy_reg(const char *source, const char *dest) { struct utimbuf tv; - tv.actime = source_stats.st_atime; - tv.modtime = source_stats.st_mtime; + tv.actime = convert_timespec_to_time_t(source_stats.st_ex_atime); + tv.modtime = convert_timespec_to_time_t(source_stats.st_ex_mtime); utime(dest, &tv); } @@ -575,13 +575,13 @@ static uint64_t vfswrap_get_alloc_size(vfs_handle_struct *handle, START_PROFILE(syscall_get_alloc_size); - if(S_ISDIR(sbuf->st_mode)) { + if(S_ISDIR(sbuf->st_ex_mode)) { result = 0; goto out; } #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE) - result = (uint64_t)STAT_ST_BLOCKSIZE * (uint64_t)sbuf->st_blocks; + result = (uint64_t)STAT_ST_BLOCKSIZE * (uint64_t)sbuf->st_ex_blocks; #else result = get_file_size_stat(sbuf); #endif @@ -777,18 +777,18 @@ static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fs if (SMB_VFS_FSTAT(fsp, &st) == -1) return -1; - space_to_write = len - st.st_size; + space_to_write = len - st.st_ex_size; #ifdef S_ISFIFO - if (S_ISFIFO(st.st_mode)) + if (S_ISFIFO(st.st_ex_mode)) return 0; #endif - if (st.st_size == len) + if (st.st_ex_size == len) return 0; /* Shrink - just ftruncate. */ - if (st.st_size > len) + if (st.st_ex_size > len) return sys_ftruncate(fsp->fh->fd, len); /* available disk space is enough or not? */ @@ -806,10 +806,10 @@ static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fs } /* Write out the real space on disk. */ - if (SMB_VFS_LSEEK(fsp, st.st_size, SEEK_SET) != st.st_size) + if (SMB_VFS_LSEEK(fsp, st.st_ex_size, SEEK_SET) != st.st_ex_size) return -1; - space_to_write = len - st.st_size; + space_to_write = len - st.st_ex_size; memset(zero_space, '\0', sizeof(zero_space)); while ( space_to_write > 0) { @@ -872,18 +872,18 @@ static int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, SMB_O } #ifdef S_ISFIFO - if (S_ISFIFO(st.st_mode)) { + if (S_ISFIFO(st.st_ex_mode)) { result = 0; goto done; } #endif - if (st.st_size == len) { + if (st.st_ex_size == len) { result = 0; goto done; } - if (st.st_size > len) { + if (st.st_ex_size > len) { /* the sys_ftruncate should have worked */ goto done; } @@ -1051,8 +1051,8 @@ static struct file_id vfswrap_file_id_create(struct vfs_handle_struct *handle, * blob */ ZERO_STRUCT(key); - key.devid = sbuf->st_dev; - key.inode = sbuf->st_ino; + key.devid = sbuf->st_ex_dev; + key.inode = sbuf->st_ex_ino; /* key.extid is unused by default. */ return key; @@ -1088,7 +1088,7 @@ static NTSTATUS vfswrap_streaminfo(vfs_handle_struct *handle, return map_nt_error_from_unix(errno); } - if (S_ISDIR(sbuf.st_mode)) { + if (S_ISDIR(sbuf.st_ex_mode)) { goto done; } @@ -1098,7 +1098,7 @@ static NTSTATUS vfswrap_streaminfo(vfs_handle_struct *handle, return NT_STATUS_NO_MEMORY; } - streams->size = sbuf.st_size; + streams->size = sbuf.st_ex_size; streams->alloc_size = SMB_VFS_GET_ALLOC_SIZE(handle->conn, fsp, &sbuf); streams->name = talloc_strdup(streams, "::$DATA"); diff --git a/source3/modules/vfs_fake_perms.c b/source3/modules/vfs_fake_perms.c index 2989322147..cc3ab6220d 100644 --- a/source3/modules/vfs_fake_perms.c +++ b/source3/modules/vfs_fake_perms.c @@ -32,13 +32,13 @@ static int fake_perms_stat(vfs_handle_struct *handle, const char *fname, SMB_STR ret = SMB_VFS_NEXT_STAT(handle, fname, sbuf); if (ret == 0) { - if (S_ISDIR(sbuf->st_mode)) { - sbuf->st_mode = S_IFDIR | S_IRWXU; + if (S_ISDIR(sbuf->st_ex_mode)) { + sbuf->st_ex_mode = S_IFDIR | S_IRWXU; } else { - sbuf->st_mode = S_IRWXU; + sbuf->st_ex_mode = S_IRWXU; } - sbuf->st_uid = handle->conn->server_info->utok.uid; - sbuf->st_gid = handle->conn->server_info->utok.gid; + sbuf->st_ex_uid = handle->conn->server_info->utok.uid; + sbuf->st_ex_gid = handle->conn->server_info->utok.gid; } return ret; @@ -50,13 +50,13 @@ static int fake_perms_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_ST ret = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf); if (ret == 0) { - if (S_ISDIR(sbuf->st_mode)) { - sbuf->st_mode = S_IFDIR | S_IRWXU; + if (S_ISDIR(sbuf->st_ex_mode)) { + sbuf->st_ex_mode = S_IFDIR | S_IRWXU; } else { - sbuf->st_mode = S_IRWXU; + sbuf->st_ex_mode = S_IRWXU; } - sbuf->st_uid = handle->conn->server_info->utok.uid; - sbuf->st_gid = handle->conn->server_info->utok.gid; + sbuf->st_ex_uid = handle->conn->server_info->utok.uid; + sbuf->st_ex_gid = handle->conn->server_info->utok.gid; } return ret; } diff --git a/source3/modules/vfs_fileid.c b/source3/modules/vfs_fileid.c index 8152c5477e..93b71a4dc0 100644 --- a/source3/modules/vfs_fileid.c +++ b/source3/modules/vfs_fileid.c @@ -237,8 +237,8 @@ static struct file_id fileid_file_id_create(struct vfs_handle_struct *handle, struct fileid_handle_data, return id); - id.devid = data->device_mapping_fn(data, sbuf->st_dev); - id.inode = sbuf->st_ino; + id.devid = data->device_mapping_fn(data, sbuf->st_ex_dev); + id.inode = sbuf->st_ex_ino; return id; } diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 7ef969d04b..2e4e7ede55 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -846,7 +846,7 @@ static int vfs_gpfs_chmod(vfs_handle_struct *handle, const char *path, mode_t mo } /* avoid chmod() if possible, to preserve acls */ - if ((st.st_mode & ~S_IFMT) == mode) { + if ((st.st_ex_mode & ~S_IFMT) == mode) { return 0; } @@ -866,7 +866,7 @@ static int vfs_gpfs_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t } /* avoid chmod() if possible, to preserve acls */ - if ((st.st_mode & ~S_IFMT) == mode) { + if ((st.st_ex_mode & ~S_IFMT) == mode) { return 0; } diff --git a/source3/modules/vfs_hpuxacl.c b/source3/modules/vfs_hpuxacl.c index f9293405fb..7d20a73d7b 100644 --- a/source3/modules/vfs_hpuxacl.c +++ b/source3/modules/vfs_hpuxacl.c @@ -252,7 +252,7 @@ int hpuxacl_sys_acl_set_file(vfs_handle_struct *handle, DEBUG(10, ("Error in stat call: %s\n", strerror(errno))); goto done; } - if (S_ISDIR(s.st_mode)) { + if (S_ISDIR(s.st_ex_mode)) { HPUX_ACL_T other_acl; int other_count; SMB_ACL_TYPE_T other_type; diff --git a/source3/modules/vfs_netatalk.c b/source3/modules/vfs_netatalk.c index e2fa0fb88a..ed35922359 100644 --- a/source3/modules/vfs_netatalk.c +++ b/source3/modules/vfs_netatalk.c @@ -82,7 +82,7 @@ static int atalk_build_paths(TALLOC_CTX *ctx, const char *path, const char *fnam sys_lstat(*orig_path, orig_info); - if (S_ISDIR(orig_info->st_mode)) { + if (S_ISDIR(orig_info->st_ex_mode)) { *adbl_path = talloc_asprintf(ctx, "%s/%s/%s/", path, &fname[ptr0], APPLEDOUBLE); } else { @@ -242,7 +242,7 @@ static int atalk_rename(struct vfs_handle_struct *handle, const char *oldname, c &adbl_info, &orig_info) != 0) goto exit_rename; - if (S_ISDIR(orig_info.st_mode) || S_ISREG(orig_info.st_mode)) { + if (S_ISDIR(orig_info.st_ex_mode) || S_ISREG(orig_info.st_ex_mode)) { DEBUG(3, ("ATALK: %s has passed..\n", adbl_path)); goto exit_rename; } @@ -298,7 +298,7 @@ static int atalk_unlink(struct vfs_handle_struct *handle, const char *path) &adbl_info, &orig_info) != 0) goto exit_unlink; - if (S_ISDIR(orig_info.st_mode) || S_ISREG(orig_info.st_mode)) { + if (S_ISDIR(orig_info.st_ex_mode) || S_ISREG(orig_info.st_ex_mode)) { DEBUG(3, ("ATALK: %s has passed..\n", adbl_path)); goto exit_unlink; } @@ -330,7 +330,7 @@ static int atalk_chmod(struct vfs_handle_struct *handle, const char *path, mode_ &adbl_info, &orig_info) != 0) goto exit_chmod; - if (!S_ISDIR(orig_info.st_mode) && !S_ISREG(orig_info.st_mode)) { + if (!S_ISDIR(orig_info.st_ex_mode) && !S_ISREG(orig_info.st_ex_mode)) { DEBUG(3, ("ATALK: %s has passed..\n", orig_path)); goto exit_chmod; } @@ -362,7 +362,7 @@ static int atalk_chown(struct vfs_handle_struct *handle, const char *path, uid_t &adbl_info, &orig_info) != 0) goto exit_chown; - if (!S_ISDIR(orig_info.st_mode) && !S_ISREG(orig_info.st_mode)) { + if (!S_ISDIR(orig_info.st_ex_mode) && !S_ISREG(orig_info.st_ex_mode)) { DEBUG(3, ("ATALK: %s has passed..\n", orig_path)); goto exit_chown; } @@ -396,7 +396,7 @@ static int atalk_lchown(struct vfs_handle_struct *handle, const char *path, uid_ &adbl_info, &orig_info) != 0) goto exit_lchown; - if (!S_ISDIR(orig_info.st_mode) && !S_ISREG(orig_info.st_mode)) { + if (!S_ISDIR(orig_info.st_ex_mode) && !S_ISREG(orig_info.st_ex_mode)) { DEBUG(3, ("ATALK: %s has passed..\n", orig_path)); goto exit_lchown; } diff --git a/source3/modules/vfs_recycle.c b/source3/modules/vfs_recycle.c index 2b0edcdb4a..f1791aa6b1 100644 --- a/source3/modules/vfs_recycle.c +++ b/source3/modules/vfs_recycle.c @@ -215,7 +215,7 @@ static bool recycle_directory_exist(vfs_handle_struct *handle, const char *dname SMB_STRUCT_STAT st; if (SMB_VFS_NEXT_STAT(handle, dname, &st) == 0) { - if (S_ISDIR(st.st_mode)) { + if (S_ISDIR(st.st_ex_mode)) { return True; } } @@ -228,7 +228,7 @@ static bool recycle_file_exist(vfs_handle_struct *handle, const char *fname) SMB_STRUCT_STAT st; if (SMB_VFS_NEXT_STAT(handle, fname, &st) == 0) { - if (S_ISREG(st.st_mode)) { + if (S_ISREG(st.st_ex_mode)) { return True; } } @@ -251,7 +251,7 @@ static SMB_OFF_T recycle_get_file_size(vfs_handle_struct *handle, const char *fn return (SMB_OFF_T)0; } - return(st.st_size); + return(st.st_ex_size); } /** @@ -402,7 +402,7 @@ static void recycle_do_touch(vfs_handle_struct *handle, const char *fname, return; } ft.atime = timespec_current(); /* atime */ - ft.mtime = touch_mtime ? ft.atime : get_mtimespec(&st); /* mtime */ + ft.mtime = touch_mtime ? ft.atime : st.st_ex_mtime; /* mtime */ become_root(); ret = SMB_VFS_NEXT_NTIMES(handle, fname, &ft); diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c index 9543af32b9..acfac57b51 100644 --- a/source3/modules/vfs_shadow_copy2.c +++ b/source3/modules/vfs_shadow_copy2.c @@ -314,7 +314,7 @@ static void convert_sbuf(vfs_handle_struct *handle, const char *fname, SMB_STRUC if (shash == 0) { shash = 1; } - sbuf->st_ino ^= shash; + sbuf->st_ex_ino ^= shash; } } diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c index e5a70b1a49..72affe402a 100644 --- a/source3/modules/vfs_streams_depot.c +++ b/source3/modules/vfs_streams_depot.c @@ -182,7 +182,7 @@ static char *stream_dir(vfs_handle_struct *handle, const char *base_path, if (SMB_VFS_NEXT_STAT(handle, result, &sbuf) == 0) { char *newname; - if (!S_ISDIR(sbuf.st_mode)) { + if (!S_ISDIR(sbuf.st_ex_mode)) { errno = EINVAL; goto fail; } @@ -504,7 +504,7 @@ static int streams_depot_unlink(vfs_handle_struct *handle, const char *fname) return -1; } - if (sbuf.st_nlink == 1) { + if (sbuf.st_ex_nlink == 1) { char *dirname = stream_dir(handle, fname, &sbuf, false); if (dirname != NULL) { @@ -652,7 +652,7 @@ static bool collect_one_stream(const char *dirname, if (!add_one_stream(state->mem_ctx, &state->num_streams, &state->streams, - dirent, sbuf.st_size, + dirent, sbuf.st_ex_size, SMB_VFS_GET_ALLOC_SIZE(state->handle->conn, NULL, &sbuf))) { state->status = NT_STATUS_NO_MEMORY; @@ -698,10 +698,10 @@ static NTSTATUS streams_depot_streaminfo(vfs_handle_struct *handle, state.streams = NULL; state.num_streams = 0; - if (!S_ISDIR(sbuf.st_mode)) { + if (!S_ISDIR(sbuf.st_ex_mode)) { if (!add_one_stream(mem_ctx, &state.num_streams, &state.streams, - "::$DATA", sbuf.st_size, + "::$DATA", sbuf.st_ex_size, SMB_VFS_GET_ALLOC_SIZE(handle->conn, fsp, &sbuf))) { return NT_STATUS_NO_MEMORY; diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c index 3d5478d7a2..ebc51e79e3 100644 --- a/source3/modules/vfs_streams_xattr.c +++ b/source3/modules/vfs_streams_xattr.c @@ -42,17 +42,17 @@ static SMB_INO_T stream_inode(const SMB_STRUCT_STAT *sbuf, const char *sname) char *upper_sname; DEBUG(10, ("stream_inode called for %lu/%lu [%s]\n", - (unsigned long)sbuf->st_dev, - (unsigned long)sbuf->st_ino, sname)); + (unsigned long)sbuf->st_ex_dev, + (unsigned long)sbuf->st_ex_ino, sname)); upper_sname = talloc_strdup_upper(talloc_tos(), sname); SMB_ASSERT(upper_sname != NULL); MD5Init(&ctx); - MD5Update(&ctx, (unsigned char *)&(sbuf->st_dev), - sizeof(sbuf->st_dev)); - MD5Update(&ctx, (unsigned char *)&(sbuf->st_ino), - sizeof(sbuf->st_ino)); + MD5Update(&ctx, (unsigned char *)&(sbuf->st_ex_dev), + sizeof(sbuf->st_ex_dev)); + MD5Update(&ctx, (unsigned char *)&(sbuf->st_ex_ino), + sizeof(sbuf->st_ex_ino)); MD5Update(&ctx, (unsigned char *)upper_sname, talloc_get_size(upper_sname)-1); MD5Final(hash, &ctx); @@ -159,18 +159,18 @@ static int streams_xattr_fstat(vfs_handle_struct *handle, files_struct *fsp, return -1; } - sbuf->st_size = get_xattr_size(handle->conn, fsp->base_fsp, + sbuf->st_ex_size = get_xattr_size(handle->conn, fsp->base_fsp, io->base, io->xattr_name); - if (sbuf->st_size == -1) { + if (sbuf->st_ex_size == -1) { return -1; } - DEBUG(10, ("sbuf->st_size = %d\n", (int)sbuf->st_size)); + DEBUG(10, ("sbuf->st_ex_size = %d\n", (int)sbuf->st_ex_size)); - sbuf->st_ino = stream_inode(sbuf, io->xattr_name); - sbuf->st_mode &= ~S_IFMT; - sbuf->st_mode |= S_IFREG; - sbuf->st_blocks = sbuf->st_size % STAT_ST_BLOCKSIZE + 1; + sbuf->st_ex_ino = stream_inode(sbuf, io->xattr_name); + sbuf->st_ex_mode &= ~S_IFMT; + sbuf->st_ex_mode |= S_IFREG; + sbuf->st_ex_blocks = sbuf->st_ex_size % STAT_ST_BLOCKSIZE + 1; return 0; } @@ -208,16 +208,16 @@ static int streams_xattr_stat(vfs_handle_struct *handle, const char *fname, goto fail; } - sbuf->st_size = get_xattr_size(handle->conn, NULL, base, xattr_name); - if (sbuf->st_size == -1) { + sbuf->st_ex_size = get_xattr_size(handle->conn, NULL, base, xattr_name); + if (sbuf->st_ex_size == -1) { errno = ENOENT; goto fail; } - sbuf->st_ino = stream_inode(sbuf, xattr_name); - sbuf->st_mode &= ~S_IFMT; - sbuf->st_mode |= S_IFREG; - sbuf->st_blocks = sbuf->st_size % STAT_ST_BLOCKSIZE + 1; + sbuf->st_ex_ino = stream_inode(sbuf, xattr_name); + sbuf->st_ex_mode &= ~S_IFMT; + sbuf->st_ex_mode |= S_IFREG; + sbuf->st_ex_blocks = sbuf->st_ex_size % STAT_ST_BLOCKSIZE + 1; result = 0; fail: @@ -259,16 +259,16 @@ static int streams_xattr_lstat(vfs_handle_struct *handle, const char *fname, goto fail; } - sbuf->st_size = get_xattr_size(handle->conn, NULL, base, xattr_name); - if (sbuf->st_size == -1) { + sbuf->st_ex_size = get_xattr_size(handle->conn, NULL, base, xattr_name); + if (sbuf->st_ex_size == -1) { errno = ENOENT; goto fail; } - sbuf->st_ino = stream_inode(sbuf, xattr_name); - sbuf->st_mode &= ~S_IFMT; - sbuf->st_mode |= S_IFREG; - sbuf->st_blocks = sbuf->st_size % STAT_ST_BLOCKSIZE + 1; + sbuf->st_ex_ino = stream_inode(sbuf, xattr_name); + sbuf->st_ex_mode &= ~S_IFMT; + sbuf->st_ex_mode |= S_IFREG; + sbuf->st_ex_blocks = sbuf->st_ex_size % STAT_ST_BLOCKSIZE + 1; result = 0; fail: @@ -740,10 +740,10 @@ static NTSTATUS streams_xattr_streaminfo(vfs_handle_struct *handle, state.streams = NULL; state.num_streams = 0; - if (!S_ISDIR(sbuf.st_mode)) { + if (!S_ISDIR(sbuf.st_ex_mode)) { if (!add_one_stream(mem_ctx, &state.num_streams, &state.streams, - "::$DATA", sbuf.st_size, + "::$DATA", sbuf.st_ex_size, SMB_VFS_GET_ALLOC_SIZE(handle->conn, fsp, &sbuf))) { return NT_STATUS_NO_MEMORY; diff --git a/source3/modules/vfs_tsmsm.c b/source3/modules/vfs_tsmsm.c index 6fb1d1d2d4..57807105f6 100644 --- a/source3/modules/vfs_tsmsm.c +++ b/source3/modules/vfs_tsmsm.c @@ -153,10 +153,12 @@ static bool tsmsm_is_offline(struct vfs_handle_struct *handle, /* if the file has more than FILE_IS_ONLINE_RATIO of blocks available, then assume it is not offline (it may not be 100%, as it could be sparse) */ - if (512 * (off_t)stbuf->st_blocks >= stbuf->st_size * tsmd->online_ratio) { + if (512 * (off_t)stbuf->st_ex_blocks >= + stbuf->st_ex_size * tsmd->online_ratio) { DEBUG(10,("%s not offline: st_blocks=%ld st_size=%ld " - "online_ratio=%.2f\n", path, (long)stbuf->st_blocks, - (long)stbuf->st_size, tsmd->online_ratio)); + "online_ratio=%.2f\n", path, + (long)stbuf->st_ex_blocks, + (long)stbuf->st_ex_size, tsmd->online_ratio)); return false; } @@ -254,9 +256,10 @@ static bool tsmsm_aio_force(struct vfs_handle_struct *handle, struct files_struc */ if(SMB_VFS_FSTAT(fsp, &sbuf) == 0) { DEBUG(10,("tsmsm_aio_force st_blocks=%ld st_size=%ld " - "online_ratio=%.2f\n", (long)sbuf.st_blocks, - (long)sbuf.st_size, tsmd->online_ratio)); - return !(512 * (off_t)sbuf.st_blocks >= sbuf.st_size * tsmd->online_ratio); + "online_ratio=%.2f\n", (long)sbuf.st_ex_blocks, + (long)sbuf.st_ex_size, tsmd->online_ratio)); + return !(512 * (off_t)sbuf.st_ex_blocks >= + sbuf.st_ex_size * tsmd->online_ratio); } return false; } diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 6da792a8d7..4bd7cb0f9d 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -351,6 +351,7 @@ struct global { int cups_connection_timeout; char *szSMBPerfcountModule; bool bMapUntrustedToDomain; + bool bFakeDirCreateTimes; }; static struct global Globals; @@ -362,7 +363,7 @@ struct service { bool valid; bool autoloaded; int usershare; - time_t usershare_last_mod; + struct timespec usershare_last_mod; char *szService; char *szPath; char *szUsername; @@ -468,7 +469,6 @@ struct service { bool bDosFilemode; bool bDosFiletimes; bool bDosFiletimeResolution; - bool bFakeDirCreateTimes; bool bBlockingLocks; bool bInheritPerms; bool bInheritACLS; @@ -506,7 +506,7 @@ static struct service sDefault = { True, /* valid */ False, /* not autoloaded */ 0, /* not a usershare */ - (time_t)0, /* No last mod time */ + {0, }, /* No last mod time */ NULL, /* szService */ NULL, /* szPath */ NULL, /* szUsername */ @@ -612,7 +612,6 @@ static struct service sDefault = { False, /* bDosFilemode */ True, /* bDosFiletimes */ False, /* bDosFiletimeResolution */ - False, /* bFakeDirCreateTimes */ True, /* bBlockingLocks */ False, /* bInheritPerms */ False, /* bInheritACLS */ @@ -4274,11 +4273,11 @@ static struct parm_struct parm_table[] = { { .label = "fake directory create times", .type = P_BOOL, - .p_class = P_LOCAL, - .ptr = &sDefault.bFakeDirCreateTimes, + .p_class = P_GLOBAL, + .ptr = &Globals.bFakeDirCreateTimes, .special = NULL, .enum_list = NULL, - .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL, + .flags = FLAG_ADVANCED | FLAG_GLOBAL, }, { .label = "panic action", @@ -5584,7 +5583,7 @@ FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles) FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode) FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes) FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution) -FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes) +FN_GLOBAL_BOOL(lp_fake_dir_create_times, &Globals.bFakeDirCreateTimes) FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks) FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms) FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS) @@ -8330,27 +8329,27 @@ static void set_allowed_client_auth(void) static bool check_usershare_stat(const char *fname, const SMB_STRUCT_STAT *psbuf) { - if (!S_ISREG(psbuf->st_mode)) { + if (!S_ISREG(psbuf->st_ex_mode)) { DEBUG(0,("check_usershare_stat: file %s owned by uid %u is " "not a regular file\n", - fname, (unsigned int)psbuf->st_uid )); + fname, (unsigned int)psbuf->st_ex_uid )); return False; } /* Ensure this doesn't have the other write bit set. */ - if (psbuf->st_mode & S_IWOTH) { + if (psbuf->st_ex_mode & S_IWOTH) { DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows " "public write. Refusing to allow as a usershare file.\n", - fname, (unsigned int)psbuf->st_uid )); + fname, (unsigned int)psbuf->st_ex_uid )); return False; } /* Should be 10k or less. */ - if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) { + if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) { DEBUG(0,("check_usershare_stat: file %s owned by uid %u is " "too large (%u) to be a user share file.\n", - fname, (unsigned int)psbuf->st_uid, - (unsigned int)psbuf->st_size )); + fname, (unsigned int)psbuf->st_ex_uid, + (unsigned int)psbuf->st_ex_size )); return False; } @@ -8509,7 +8508,7 @@ enum usershare_err parse_usershare_file(TALLOC_CTX *ctx, sys_closedir(dp); - if (!S_ISDIR(sbuf.st_mode)) { + if (!S_ISDIR(sbuf.st_ex_mode)) { DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n", servicename, sharepath )); return USERSHARE_PATH_NOT_DIRECTORY; @@ -8521,7 +8520,7 @@ enum usershare_err parse_usershare_file(TALLOC_CTX *ctx, if (lp_usershare_owner_only()) { /* root can share anything. */ - if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) { + if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) { return USERSHARE_PATH_NOT_ALLOWED; } } @@ -8599,7 +8598,9 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i TALLOC_FREE(canon_name); } - if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) { + if (iService != -1 && + timespec_compare(&ServicePtrs[iService]->usershare_last_mod, + &lsbuf.st_ex_mtime) == 0) { /* Nothing changed - Mark valid and return. */ DEBUG(10,("process_usershare_file: service %s not changed.\n", service_name )); @@ -8632,7 +8633,7 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i } /* Is it the same dev/inode as was lstated ? */ - if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) { + if (lsbuf.st_ex_dev != sbuf.st_ex_dev || lsbuf.st_ex_ino != sbuf.st_ex_ino) { close(fd); DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. " "Symlink spoofing going on ?\n", fname )); @@ -8652,7 +8653,7 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i close(fd); if (lines == NULL) { DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n", - fname, (unsigned int)sbuf.st_uid )); + fname, (unsigned int)sbuf.st_ex_uid )); SAFE_FREE(fname); return -1; } @@ -8716,7 +8717,7 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i } /* And note when it was loaded. */ - ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime; + ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime; string_set(&ServicePtrs[iService]->szPath, sharepath); string_set(&ServicePtrs[iService]->comment, comment); @@ -8729,7 +8730,7 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i Checks if a usershare entry has been modified since last load. ***************************************************************************/ -static bool usershare_exists(int iService, time_t *last_mod) +static bool usershare_exists(int iService, struct timespec *last_mod) { SMB_STRUCT_STAT lsbuf; const char *usersharepath = Globals.szUsersharePath; @@ -8746,13 +8747,13 @@ static bool usershare_exists(int iService, time_t *last_mod) return false; } - if (!S_ISREG(lsbuf.st_mode)) { + if (!S_ISREG(lsbuf.st_ex_mode)) { SAFE_FREE(fname); return false; } SAFE_FREE(fname); - *last_mod = lsbuf.st_mtime; + *last_mod = lsbuf.st_ex_mtime; return true; } @@ -8777,7 +8778,7 @@ int load_usershare_service(const char *servicename) return -1; } - if (!S_ISDIR(sbuf.st_mode)) { + if (!S_ISDIR(sbuf.st_ex_mode)) { DEBUG(0,("load_usershare_service: %s is not a directory.\n", usersharepath )); return -1; @@ -8789,9 +8790,9 @@ int load_usershare_service(const char *servicename) */ #ifdef S_ISVTX - if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) { + if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) { #else - if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) { + if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) { #endif DEBUG(0,("load_usershare_service: directory %s is not owned by root " "or does not have the sticky bit 't' set or is writable by anyone.\n", @@ -8860,9 +8861,9 @@ int load_usershare_shares(void) */ #ifdef S_ISVTX - if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) { + if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) { #else - if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) { + if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) { #endif DEBUG(0,("load_usershare_shares: directory %s is not owned by root " "or does not have the sticky bit 't' set or is writable by anyone.\n", @@ -9263,7 +9264,7 @@ int lp_servicenumber(const char *pszServiceName) } if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) { - time_t last_mod; + struct timespec last_mod; if (!usershare_exists(iService, &last_mod)) { /* Remove the share security tdb entry for it. */ @@ -9275,7 +9276,8 @@ int lp_servicenumber(const char *pszServiceName) } /* Has it been modified ? If so delete and reload. */ - if (ServicePtrs[iService]->usershare_last_mod < last_mod) { + if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod, + &last_mod) < 0) { /* Remove it from the array. */ free_service_byindex(iService); /* and now reload it. */ diff --git a/source3/passdb/pdb_smbpasswd.c b/source3/passdb/pdb_smbpasswd.c index d663c7f0b2..8074b2e3a1 100644 --- a/source3/passdb/pdb_smbpasswd.c +++ b/source3/passdb/pdb_smbpasswd.c @@ -292,7 +292,7 @@ Error was %s\n", pfile, strerror(errno))); return NULL; } - if( sbuf1.st_ino == sbuf2.st_ino) { + if( sbuf1.st_ex_ino == sbuf2.st_ex_ino) { /* No race. */ break; } diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 39e9661bd6..a05e0def7b 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -1352,7 +1352,7 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr if (SMB_VFS_FSTAT(fsp, &st) == -1) { goto error_exit; } - old_create_time = st.st_mtime; + old_create_time = convert_timespec_to_time_t(st.st_ex_mtime); DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", (long)old_create_time)); } @@ -1404,7 +1404,7 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr if (SMB_VFS_FSTAT(fsp, &st) == -1) { goto error_exit; } - new_create_time = st.st_mtime; + new_create_time = convert_timespec_to_time_t(st.st_ex_mtime); DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", (long)new_create_time)); } diff --git a/source3/printing/printfsp.c b/source3/printing/printfsp.c index 243b8ea03b..a8e175a684 100644 --- a/source3/printing/printfsp.c +++ b/source3/printing/printfsp.c @@ -75,7 +75,7 @@ NTSTATUS print_fsp_open(struct smb_request *req, connection_struct *conn, string_set(&fsp->fsp_name,print_job_fname(lp_const_servicename(SNUM(conn)),jobid)); fsp->wcp = NULL; SMB_VFS_FSTAT(fsp, psbuf); - fsp->mode = psbuf->st_mode; + fsp->mode = psbuf->st_ex_mode; fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf); return NT_STATUS_OK; diff --git a/source3/printing/printing.c b/source3/printing/printing.c index ce98792096..3f337d01be 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -2563,7 +2563,7 @@ bool print_job_end(int snum, uint32 jobid, enum file_close_type close_type) if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) && (sys_fstat(pjob->fd, &sbuf) == 0)) { - pjob->size = sbuf.st_size; + pjob->size = sbuf.st_ex_size; close(pjob->fd); pjob->fd = -1; } else { diff --git a/source3/registry/regfio.c b/source3/registry/regfio.c index cc6a6f4103..38411d8556 100644 --- a/source3/registry/regfio.c +++ b/source3/registry/regfio.c @@ -84,7 +84,7 @@ static int read_block( REGF_FILE *file, prs_struct *ps, uint32 file_offset, uint return -1; } - if ( (size_t)file_offset >= sbuf.st_size ) + if ( (size_t)file_offset >= sbuf.st_ex_size ) return -1; /* if block_size == 0, we are parsing HBIN records and need @@ -1434,7 +1434,7 @@ static REGF_HBIN* regf_hbin_allocate( REGF_FILE *file, uint32 block_size ) return NULL; } - hbin->file_off = sbuf.st_size; + hbin->file_off = sbuf.st_ex_size; hbin->free_off = HBIN_HEADER_REC_SIZE; hbin->free_size = block_size - hbin->free_off + sizeof(uint32);; diff --git a/source3/smbd/close.c b/source3/smbd/close.c index d23b509af2..9aab3a7405 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -103,7 +103,7 @@ static void check_magic(struct files_struct *fsp) return; } - transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_size); + transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_ex_size); close(tmp_fd); close(outfd); TALLOC_FREE(ctx); diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index ab4a0d27e3..f5a9e22d14 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -824,7 +824,7 @@ bool get_dir_entry(TALLOC_CTX *ctx, char **pp_fname_out, SMB_OFF_T *size, uint32 *mode, - time_t *date, + struct timespec *date, bool check_descend, bool ask_sharemode) { @@ -910,8 +910,8 @@ bool get_dir_entry(TALLOC_CTX *ctx, continue; } - *size = sbuf.st_size; - *date = sbuf.st_mtime; + *size = sbuf.st_ex_size; + *date = sbuf.st_ex_mtime; if (ask_sharemode) { struct timespec write_time_ts; @@ -920,7 +920,7 @@ bool get_dir_entry(TALLOC_CTX *ctx, fileid = vfs_file_id_from_sbuf(conn, &sbuf); get_file_infos(fileid, NULL, &write_time_ts); if (!null_timespec(write_time_ts)) { - *date = convert_timespec_to_time_t(write_time_ts); + *date = write_time_ts; } } @@ -989,7 +989,7 @@ static bool user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_ /* Pseudo-open the file */ - if(S_ISDIR(pst->st_mode)) { + if(S_ISDIR(pst->st_ex_mode)) { return True; } @@ -1012,7 +1012,7 @@ static bool file_is_special(connection_struct *conn, char *name, SMB_STRUCT_STAT SMB_ASSERT(VALID_STAT(*pst)); - if (S_ISREG(pst->st_mode) || S_ISDIR(pst->st_mode) || S_ISLNK(pst->st_mode)) + if (S_ISREG(pst->st_ex_mode) || S_ISDIR(pst->st_ex_mode) || S_ISLNK(pst->st_ex_mode)) return False; return True; diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 5ae7151303..9a3470312f 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -23,7 +23,7 @@ static int set_sparse_flag(const SMB_STRUCT_STAT * const sbuf) { #if defined (HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE) - if (sbuf->st_size > sbuf->st_blocks * (SMB_OFF_T)STAT_ST_BLOCKSIZE) { + if (sbuf->st_ex_size > sbuf->st_ex_blocks * (SMB_OFF_T)STAT_ST_BLOCKSIZE) { return FILE_ATTRIBUTE_SPARSE; } #endif @@ -88,7 +88,7 @@ mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname, } /* Save for later - but explicitly remove setuid bit for safety. */ - dir_mode = sbuf.st_mode & ~S_ISUID; + dir_mode = sbuf.st_ex_mode & ~S_ISUID; DEBUG(2,("unix_mode(%s) inherit mode %o\n",fname,(int)dir_mode)); /* Clear "result" */ result = 0; @@ -147,7 +147,7 @@ static uint32 dos_mode_from_sbuf(connection_struct *conn, const char *path, SMB_ if (ro_opts == MAP_READONLY_YES) { /* Original Samba method - map inverse of user "w" bit. */ - if ((sbuf->st_mode & S_IWUSR) == 0) { + if ((sbuf->st_ex_mode & S_IWUSR) == 0) { result |= aRONLY; } } else if (ro_opts == MAP_READONLY_PERMISSIONS) { @@ -157,16 +157,16 @@ static uint32 dos_mode_from_sbuf(connection_struct *conn, const char *path, SMB_ } } /* Else never set the readonly bit. */ - if (MAP_ARCHIVE(conn) && ((sbuf->st_mode & S_IXUSR) != 0)) + if (MAP_ARCHIVE(conn) && ((sbuf->st_ex_mode & S_IXUSR) != 0)) result |= aARCH; - if (MAP_SYSTEM(conn) && ((sbuf->st_mode & S_IXGRP) != 0)) + if (MAP_SYSTEM(conn) && ((sbuf->st_ex_mode & S_IXGRP) != 0)) result |= aSYSTEM; - if (MAP_HIDDEN(conn) && ((sbuf->st_mode & S_IXOTH) != 0)) + if (MAP_HIDDEN(conn) && ((sbuf->st_ex_mode & S_IXOTH) != 0)) result |= aHIDDEN; - if (S_ISDIR(sbuf->st_mode)) + if (S_ISDIR(sbuf->st_ex_mode)) result = aDIR | (result & aRONLY); result |= set_sparse_flag(sbuf); @@ -225,7 +225,7 @@ static bool get_ea_dos_attribute(connection_struct *conn, const char *path,SMB_S return False; } - if (S_ISDIR(sbuf->st_mode)) { + if (S_ISDIR(sbuf->st_ex_mode)) { dosattr |= aDIR; } *pattr = (uint32)(dosattr & SAMBA_ATTRIBUTES_MASK); @@ -406,7 +406,7 @@ static bool get_stat_dos_flags(connection_struct *conn, *dosmode |= aSYSTEM; if (sbuf->st_flags & UF_DOS_NOINDEX) *dosmode |= FILE_ATTRIBUTE_NONINDEXED; - if (S_ISDIR(sbuf->st_mode)) + if (S_ISDIR(sbuf->st_ex_mode)) *dosmode |= aDIR; *dosmode |= set_sparse_flag(sbuf); @@ -508,7 +508,7 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf) offline = SMB_VFS_IS_OFFLINE(conn, path, sbuf); - if (S_ISREG(sbuf->st_mode) && offline) { + if (S_ISREG(sbuf->st_ex_mode) && offline) { result |= FILE_ATTRIBUTE_OFFLINE; } @@ -563,11 +563,11 @@ int file_set_dosmode(connection_struct *conn, const char *fname, return(-1); } - unixmode = st->st_mode; + unixmode = st->st_ex_mode; - get_acl_group_bits(conn, fname, &st->st_mode); + get_acl_group_bits(conn, fname, &st->st_ex_mode); - if (S_ISDIR(st->st_mode)) + if (S_ISDIR(st->st_ex_mode)) dosmode |= aDIR; else dosmode &= ~aDIR; @@ -590,7 +590,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname, old_mode &= ~FILE_ATTRIBUTE_OFFLINE; if (old_mode == dosmode) { - st->st_mode = unixmode; + st->st_ex_mode = unixmode; return(0); } @@ -605,7 +605,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname, notify_fname(conn, NOTIFY_ACTION_MODIFIED, FILE_NOTIFY_CHANGE_ATTRIBUTES, fname); } - st->st_mode = unixmode; + st->st_ex_mode = unixmode; return 0; } } @@ -617,7 +617,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname, notify_fname(conn, NOTIFY_ACTION_MODIFIED, FILE_NOTIFY_CHANGE_ATTRIBUTES, fname); } - st->st_mode = unixmode; + st->st_ex_mode = unixmode; return 0; } @@ -639,10 +639,10 @@ int file_set_dosmode(connection_struct *conn, const char *fname, if (!MAP_HIDDEN(conn)) mask |= S_IXOTH; - unixmode |= (st->st_mode & mask); + unixmode |= (st->st_ex_mode & mask); /* if we previously had any r bits set then leave them alone */ - if ((tmp = st->st_mode & (S_IRUSR|S_IRGRP|S_IROTH))) { + if ((tmp = st->st_ex_mode & (S_IRUSR|S_IRGRP|S_IROTH))) { unixmode &= ~(S_IRUSR|S_IRGRP|S_IROTH); unixmode |= tmp; } @@ -650,7 +650,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname, /* if we previously had any w bits set then leave them alone whilst adding in the new w bits, if the new mode is not rdonly */ if (!IS_DOS_READONLY(dosmode)) { - unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)); + unixmode |= (st->st_ex_mode & (S_IWUSR|S_IWGRP|S_IWOTH)); } ret = SMB_VFS_CHMOD(conn, fname, unixmode); @@ -659,7 +659,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname, notify_fname(conn, NOTIFY_ACTION_MODIFIED, FILE_NOTIFY_CHANGE_ATTRIBUTES, fname); } - st->st_mode = unixmode; + st->st_ex_mode = unixmode; return 0; } @@ -696,7 +696,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname, FILE_NOTIFY_CHANGE_ATTRIBUTES, fname); } if (ret == 0) { - st->st_mode = unixmode; + st->st_ex_mode = unixmode; } } diff --git a/source3/smbd/file_access.c b/source3/smbd/file_access.c index abffcd2f4f..a248dd9f3b 100644 --- a/source3/smbd/file_access.c +++ b/source3/smbd/file_access.c @@ -80,7 +80,7 @@ bool can_delete_file_in_directory(connection_struct *conn, const char *fname) /* fast paths first */ - if (!S_ISDIR(sbuf.st_mode)) { + if (!S_ISDIR(sbuf.st_ex_mode)) { return False; } if (conn->server_info->utok.uid == 0 || conn->admin_user) { @@ -90,7 +90,7 @@ bool can_delete_file_in_directory(connection_struct *conn, const char *fname) #ifdef S_ISVTX /* sticky bit means delete only by owner or root. */ - if (sbuf.st_mode & S_ISVTX) { + if (sbuf.st_ex_mode & S_ISVTX) { SMB_STRUCT_STAT sbuf_file; if(SMB_VFS_STAT(conn, fname, &sbuf_file) != 0) { if (errno == ENOENT) { @@ -105,7 +105,7 @@ bool can_delete_file_in_directory(connection_struct *conn, const char *fname) * for bug #3348. Don't assume owning sticky bit * directory means write access allowed. */ - if (conn->server_info->utok.uid != sbuf_file.st_uid) { + if (conn->server_info->utok.uid != sbuf_file.st_ex_uid) { return False; } } @@ -156,17 +156,17 @@ bool can_access_file_data(connection_struct *conn, const char *fname, SMB_STRUCT } /* Check primary owner access. */ - if (conn->server_info->utok.uid == psbuf->st_uid) { + if (conn->server_info->utok.uid == psbuf->st_ex_uid) { switch (access_mask) { case FILE_READ_DATA: - return (psbuf->st_mode & S_IRUSR) ? True : False; + return (psbuf->st_ex_mode & S_IRUSR) ? True : False; case FILE_WRITE_DATA: - return (psbuf->st_mode & S_IWUSR) ? True : False; + return (psbuf->st_ex_mode & S_IWUSR) ? True : False; default: /* FILE_READ_DATA|FILE_WRITE_DATA */ - if ((psbuf->st_mode & (S_IWUSR|S_IRUSR)) == (S_IWUSR|S_IRUSR)) { + if ((psbuf->st_ex_mode & (S_IWUSR|S_IRUSR)) == (S_IWUSR|S_IRUSR)) { return True; } else { return False; diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index adf664b396..de5f83c868 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -296,7 +296,7 @@ ssize_t write_file(struct smb_request *req, */ if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && !wcp) { - setup_write_cache(fsp, st.st_size); + setup_write_cache(fsp, st.st_ex_size); wcp = fsp->wcp; } } diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 36503483a8..72b4ab7aa6 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -424,7 +424,7 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, * It exists. it must either be a directory or this must * be the last part of the path for it to be OK. */ - if (end && !(st.st_mode & S_IFDIR)) { + if (end && !S_ISDIR(st.st_ex_mode)) { /* * An intermediate part of the name isn't * a directory. diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c index 7f99a186aa..e2f31f077c 100644 --- a/source3/smbd/msdfs.c +++ b/source3/smbd/msdfs.c @@ -443,7 +443,7 @@ static bool is_msdfs_link_internal(TALLOC_CTX *ctx, goto err; } - if (!S_ISLNK(sbufp->st_mode)) { + if (!S_ISLNK(sbufp->st_ex_mode)) { DEBUG(5,("is_msdfs_link_read_target: %s is not a link.\n", path)); goto err; diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 204cdf9e31..d6be35d29b 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -570,7 +570,7 @@ void reply_ntcreate_and_X(struct smb_request *req) oplock_granted = NO_OPLOCK_RETURN; } - file_len = sbuf.st_size; + file_len = sbuf.st_ex_size; fattr = dos_mode(conn,fsp->fsp_name,&sbuf); if (fattr == 0) { fattr = FILE_ATTRIBUTE_NORMAL; @@ -604,10 +604,9 @@ void reply_ntcreate_and_X(struct smb_request *req) p += 4; /* Create time. */ - c_timespec = get_create_timespec( - &sbuf,lp_fake_dir_create_times(SNUM(conn))); - a_timespec = get_atimespec(&sbuf); - m_timespec = get_mtimespec(&sbuf); + c_timespec = sbuf.st_ex_btime; + a_timespec = sbuf.st_ex_atime; + m_timespec = sbuf.st_ex_mtime; if (lp_dos_filetime_resolution(SNUM(conn))) { dos_filetime_timespec(&c_timespec); @@ -1037,7 +1036,7 @@ static void call_nt_transact_create(connection_struct *conn, oplock_granted = NO_OPLOCK_RETURN; } - file_len = sbuf.st_size; + file_len = sbuf.st_ex_size; fattr = dos_mode(conn,fsp->fsp_name,&sbuf); if (fattr == 0) { fattr = FILE_ATTRIBUTE_NORMAL; @@ -1071,10 +1070,9 @@ static void call_nt_transact_create(connection_struct *conn, p += 8; /* Create time. */ - c_timespec = get_create_timespec( - &sbuf,lp_fake_dir_create_times(SNUM(conn))); - a_timespec = get_atimespec(&sbuf); - m_timespec = get_mtimespec(&sbuf); + c_timespec = sbuf.st_ex_btime; + a_timespec = sbuf.st_ex_atime; + m_timespec = sbuf.st_ex_mtime; if (lp_dos_filetime_resolution(SNUM(conn))) { dos_filetime_timespec(&c_timespec); @@ -1220,7 +1218,7 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx, } /* No links from a directory. */ - if (S_ISDIR(smb_fname->st.st_mode)) { + if (S_ISDIR(smb_fname->st.st_ex_mode)) { status = NT_STATUS_FILE_IS_A_DIRECTORY; goto out; } @@ -1283,8 +1281,8 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx, goto out; } - if (smb_fname->st.st_size) { - ret = vfs_transfer_file(fsp1, fsp2, smb_fname->st.st_size); + if (smb_fname->st.st_ex_size) { + ret = vfs_transfer_file(fsp1, fsp2, smb_fname->st.st_ex_size); } /* @@ -1296,7 +1294,7 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx, close_file(NULL, fsp1, NORMAL_CLOSE); /* Ensure the modtime is set correctly on the destination file. */ - set_close_write_time(fsp2, get_mtimespec(&smb_fname->st)); + set_close_write_time(fsp2, smb_fname->st.st_ex_mtime); status = close_file(NULL, fsp2, NORMAL_CLOSE); @@ -1311,7 +1309,7 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx, false); TALLOC_FREE(parent); - if (ret < (SMB_OFF_T)smb_fname->st.st_size) { + if (ret < (SMB_OFF_T)smb_fname->st.st_ex_size) { status = NT_STATUS_DISK_FULL; goto out; } diff --git a/source3/smbd/open.c b/source3/smbd/open.c index e6f523a162..c1b29f68f3 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -206,19 +206,19 @@ void change_file_owner_to_parent(connection_struct *conn, } become_root(); - ret = SMB_VFS_FCHOWN(fsp, parent_st.st_uid, (gid_t)-1); + ret = SMB_VFS_FCHOWN(fsp, parent_st.st_ex_uid, (gid_t)-1); unbecome_root(); if (ret == -1) { DEBUG(0,("change_file_owner_to_parent: failed to fchown " "file %s to parent directory uid %u. Error " "was %s\n", fsp->fsp_name, - (unsigned int)parent_st.st_uid, + (unsigned int)parent_st.st_ex_uid, strerror(errno) )); } DEBUG(10,("change_file_owner_to_parent: changed new file %s to " "parent directory uid %u.\n", fsp->fsp_name, - (unsigned int)parent_st.st_uid )); + (unsigned int)parent_st.st_ex_uid )); } NTSTATUS change_dir_owner_to_parent(connection_struct *conn, @@ -276,9 +276,9 @@ NTSTATUS change_dir_owner_to_parent(connection_struct *conn, } /* Ensure we're pointing at the same place. */ - if (sbuf.st_dev != psbuf->st_dev || - sbuf.st_ino != psbuf->st_ino || - sbuf.st_mode != psbuf->st_mode ) { + if (sbuf.st_ex_dev != psbuf->st_ex_dev || + sbuf.st_ex_ino != psbuf->st_ex_ino || + sbuf.st_ex_mode != psbuf->st_ex_mode ) { DEBUG(0,("change_dir_owner_to_parent: " "device/inode/mode on directory %s changed. " "Refusing to chown !\n", fname )); @@ -287,20 +287,20 @@ NTSTATUS change_dir_owner_to_parent(connection_struct *conn, } become_root(); - ret = SMB_VFS_CHOWN(conn, ".", parent_st.st_uid, (gid_t)-1); + ret = SMB_VFS_CHOWN(conn, ".", parent_st.st_ex_uid, (gid_t)-1); unbecome_root(); if (ret == -1) { status = map_nt_error_from_unix(errno); DEBUG(10,("change_dir_owner_to_parent: failed to chown " "directory %s to parent directory uid %u. " "Error was %s\n", fname, - (unsigned int)parent_st.st_uid, strerror(errno) )); + (unsigned int)parent_st.st_ex_uid, strerror(errno) )); goto out; } DEBUG(10,("change_dir_owner_to_parent: changed ownership of new " "directory %s to parent directory uid %u.\n", - fname, (unsigned int)parent_st.st_uid )); + fname, (unsigned int)parent_st.st_ex_uid )); out: @@ -396,7 +396,7 @@ static NTSTATUS open_file(files_struct *fsp, * open flags. JRA. */ - if (file_existed && S_ISFIFO(psbuf->st_mode)) { + if (file_existed && S_ISFIFO(psbuf->st_ex_mode)) { local_flags |= O_NONBLOCK; } #endif @@ -498,7 +498,7 @@ static NTSTATUS open_file(files_struct *fsp, } } else if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) && fsp->posix_open && - S_ISLNK(psbuf->st_mode)) { + S_ISLNK(psbuf->st_ex_mode)) { /* This is a POSIX stat open for delete * or rename on a symlink that points * nowhere. Allow. */ @@ -543,13 +543,13 @@ static NTSTATUS open_file(files_struct *fsp, * so catch a directory open and return an EISDIR. JRA. */ - if(S_ISDIR(psbuf->st_mode)) { + if(S_ISDIR(psbuf->st_ex_mode)) { fd_close(fsp); errno = EISDIR; return NT_STATUS_FILE_IS_A_DIRECTORY; } - fsp->mode = psbuf->st_mode; + fsp->mode = psbuf->st_ex_mode; fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf); fsp->vuid = req ? req->vuid : UID_FIELD_INVALID; fsp->file_pid = req ? req->smbpid : 0; @@ -1583,7 +1583,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, DEBUG(5,("open_file_ntcreate: FILE_CREATE " "requested for file %s and file " "already exists.\n", fname )); - if (S_ISDIR(psbuf->st_mode)) { + if (S_ISDIR(psbuf->st_ex_mode)) { errno = EISDIR; } else { errno = EEXIST; @@ -1610,13 +1610,13 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, (create_disposition == FILE_OVERWRITE_IF))) { if (!open_match_attributes(conn, fname, existing_dos_attributes, - new_dos_attributes, psbuf->st_mode, + new_dos_attributes, psbuf->st_ex_mode, unx_mode, &new_unx_mode)) { DEBUG(5,("open_file_ntcreate: attributes missmatch " "for file %s (%x %x) (0%o, 0%o)\n", fname, existing_dos_attributes, new_dos_attributes, - (unsigned int)psbuf->st_mode, + (unsigned int)psbuf->st_ex_mode, (unsigned int)unx_mode )); errno = EACCES; return NT_STATUS_ACCESS_DENIED; @@ -1715,7 +1715,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, } if (file_existed) { - struct timespec old_write_time = get_mtimespec(psbuf); + struct timespec old_write_time = psbuf->st_ex_mtime; id = vfs_file_id_from_sbuf(conn, psbuf); lck = get_share_mode_lock(talloc_tos(), id, @@ -1919,7 +1919,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, } if (!file_existed) { - struct timespec old_write_time = get_mtimespec(psbuf); + struct timespec old_write_time = psbuf->st_ex_mtime; /* * Deal with the race condition where two smbd's detect the * file doesn't exist and do the create at the same time. One @@ -2134,7 +2134,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, new_dos_attributes | aARCH, &tmp_sbuf, parent_dir, true) == 0) { - unx_mode = tmp_sbuf.st_mode; + unx_mode = tmp_sbuf.st_ex_mode; } } } @@ -2305,7 +2305,7 @@ static NTSTATUS mkdir_internal(connection_struct *conn, return map_nt_error_from_unix(errno); } - if (!S_ISDIR(psbuf->st_mode)) { + if (!S_ISDIR(psbuf->st_ex_mode)) { DEBUG(0, ("Directory just '%s' created is not a directory\n", name)); return NT_STATUS_ACCESS_DENIED; @@ -2331,9 +2331,9 @@ static NTSTATUS mkdir_internal(connection_struct *conn, * Consider bits automagically set by UNIX, i.e. SGID bit from parent * dir. */ - if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) && (mode & ~psbuf->st_mode)) { + if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) && (mode & ~psbuf->st_ex_mode)) { SMB_VFS_CHMOD(conn, name, - psbuf->st_mode | (mode & ~psbuf->st_mode)); + psbuf->st_ex_mode | (mode & ~psbuf->st_ex_mode)); } } @@ -2475,7 +2475,7 @@ static NTSTATUS open_directory(connection_struct *conn, return NT_STATUS_INVALID_PARAMETER; } - if(!S_ISDIR(psbuf->st_mode)) { + if(!S_ISDIR(psbuf->st_ex_mode)) { DEBUG(5,("open_directory: %s is not a directory !\n", fname )); return NT_STATUS_NOT_A_DIRECTORY; @@ -2524,7 +2524,7 @@ static NTSTATUS open_directory(connection_struct *conn, * Setup the files_struct for it. */ - fsp->mode = psbuf->st_mode; + fsp->mode = psbuf->st_ex_mode; fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf); fsp->vuid = req ? req->vuid : UID_FIELD_INVALID; fsp->file_pid = req ? req->smbpid : 0; @@ -2547,7 +2547,7 @@ static NTSTATUS open_directory(connection_struct *conn, string_set(&fsp->fsp_name,fname); - mtimespec = get_mtimespec(psbuf); + mtimespec = psbuf->st_ex_mtime; lck = get_share_mode_lock(talloc_tos(), fsp->file_id, conn->connectpath, @@ -3161,7 +3161,7 @@ static NTSTATUS create_file_unixpath(connection_struct *conn, } } - if (!fsp->is_directory && S_ISDIR(sbuf.st_mode)) { + if (!fsp->is_directory && S_ISDIR(sbuf.st_ex_mode)) { status = NT_STATUS_ACCESS_DENIED; goto fail; } @@ -3169,7 +3169,7 @@ static NTSTATUS create_file_unixpath(connection_struct *conn, /* Save the requested allocation size. */ if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) { if (allocation_size - && (allocation_size > sbuf.st_size)) { + && (allocation_size > sbuf.st_ex_size)) { fsp->initial_allocation_size = smb_roundup( fsp->conn, allocation_size); if (fsp->is_directory) { @@ -3184,7 +3184,7 @@ static NTSTATUS create_file_unixpath(connection_struct *conn, } } else { fsp->initial_allocation_size = smb_roundup( - fsp->conn, (uint64_t)sbuf.st_size); + fsp->conn, (uint64_t)sbuf.st_ex_size); } } diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 8d172e17bd..08b1c8c41a 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -884,8 +884,8 @@ static int map_acl_perms_to_permset(connection_struct *conn, mode_t mode, SMB_AC void create_file_sids(const SMB_STRUCT_STAT *psbuf, DOM_SID *powner_sid, DOM_SID *pgroup_sid) { - uid_to_sid( powner_sid, psbuf->st_uid ); - gid_to_sid( pgroup_sid, psbuf->st_gid ); + uid_to_sid( powner_sid, psbuf->st_ex_uid ); + gid_to_sid( pgroup_sid, psbuf->st_ex_gid ); } /**************************************************************************** @@ -1369,7 +1369,7 @@ static bool ensure_canon_entry_valid(canon_ace **pp_ace, ZERO_STRUCTP(pace); pace->type = SMB_ACL_USER_OBJ; pace->owner_type = UID_ACE; - pace->unix_ug.uid = pst->st_uid; + pace->unix_ug.uid = pst->st_ex_uid; pace->trustee = *pfile_owner_sid; pace->attr = ALLOW_ACE; @@ -1399,7 +1399,7 @@ static bool ensure_canon_entry_valid(canon_ace **pp_ace, apply_default_perms(params, is_directory, pace, S_IRUSR); } else { - pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IRUSR, S_IWUSR, S_IXUSR); + pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IRUSR, S_IWUSR, S_IXUSR); } DLIST_ADD(*pp_ace, pace); @@ -1414,7 +1414,7 @@ static bool ensure_canon_entry_valid(canon_ace **pp_ace, ZERO_STRUCTP(pace); pace->type = SMB_ACL_GROUP_OBJ; pace->owner_type = GID_ACE; - pace->unix_ug.uid = pst->st_gid; + pace->unix_ug.uid = pst->st_ex_gid; pace->trustee = *pfile_grp_sid; pace->attr = ALLOW_ACE; if (setting_acl) { @@ -1425,7 +1425,7 @@ static bool ensure_canon_entry_valid(canon_ace **pp_ace, pace->perms = 0; apply_default_perms(params, is_directory, pace, S_IRGRP); } else { - pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IRGRP, S_IWGRP, S_IXGRP); + pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IRGRP, S_IWGRP, S_IXGRP); } DLIST_ADD(*pp_ace, pace); @@ -1447,7 +1447,7 @@ static bool ensure_canon_entry_valid(canon_ace **pp_ace, pace->perms = 0; apply_default_perms(params, is_directory, pace, S_IROTH); } else - pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IROTH, S_IWOTH, S_IXOTH); + pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IROTH, S_IWOTH, S_IXOTH); DLIST_ADD(*pp_ace, pace); } @@ -1625,7 +1625,7 @@ static bool create_canon_ace_lists(files_struct *fsp, current_ace->type = SMB_ACL_OTHER; } else if (sid_equal(¤t_ace->trustee, &global_sid_Creator_Owner)) { current_ace->owner_type = UID_ACE; - current_ace->unix_ug.uid = pst->st_uid; + current_ace->unix_ug.uid = pst->st_ex_uid; current_ace->type = SMB_ACL_USER_OBJ; /* @@ -1638,7 +1638,7 @@ static bool create_canon_ace_lists(files_struct *fsp, psa->flags |= SEC_ACE_FLAG_INHERIT_ONLY; } else if (sid_equal(¤t_ace->trustee, &global_sid_Creator_Group)) { current_ace->owner_type = GID_ACE; - current_ace->unix_ug.gid = pst->st_gid; + current_ace->unix_ug.gid = pst->st_ex_gid; current_ace->type = SMB_ACL_GROUP_OBJ; /* @@ -1653,7 +1653,7 @@ static bool create_canon_ace_lists(files_struct *fsp, current_ace->owner_type = UID_ACE; /* If it's the owning user, this is a user_obj, not * a user. */ - if (current_ace->unix_ug.uid == pst->st_uid) { + if (current_ace->unix_ug.uid == pst->st_ex_uid) { current_ace->type = SMB_ACL_USER_OBJ; } else { current_ace->type = SMB_ACL_USER; @@ -1662,7 +1662,7 @@ static bool create_canon_ace_lists(files_struct *fsp, current_ace->owner_type = GID_ACE; /* If it's the primary group, this is a group_obj, not * a group. */ - if (current_ace->unix_ug.gid == pst->st_gid) { + if (current_ace->unix_ug.gid == pst->st_ex_gid) { current_ace->type = SMB_ACL_GROUP_OBJ; } else { current_ace->type = SMB_ACL_GROUP; @@ -2272,7 +2272,7 @@ static bool unpack_canon_ace(files_struct *fsp, * A default 3 element mode entry for a directory should be rwx --- ---. */ - pst->st_mode = create_default_mode(fsp, False); + pst->st_ex_mode = create_default_mode(fsp, False); if (!ensure_canon_entry_valid(&file_ace, fsp->conn->params, fsp->is_directory, pfile_owner_sid, pfile_grp_sid, pst, True)) { free_canon_ace_list(file_ace); @@ -2288,7 +2288,7 @@ static bool unpack_canon_ace(files_struct *fsp, * it's a directory. */ - pst->st_mode = create_default_mode(fsp, True); + pst->st_ex_mode = create_default_mode(fsp, True); if (dir_ace && !ensure_canon_entry_valid(&dir_ace, fsp->conn->params, fsp->is_directory, pfile_owner_sid, pfile_grp_sid, pst, True)) { free_canon_ace_list(file_ace); @@ -2402,7 +2402,7 @@ static canon_ace *canonicalise_acl(struct connection_struct *conn, case SMB_ACL_USER_OBJ: /* Get the SID from the owner. */ sid_copy(&sid, powner); - unix_ug.uid = psbuf->st_uid; + unix_ug.uid = psbuf->st_ex_uid; owner_type = UID_ACE; break; case SMB_ACL_USER: @@ -2419,7 +2419,7 @@ static canon_ace *canonicalise_acl(struct connection_struct *conn, * entries out of the blue when setting ACLs, so a get/set * cycle will drop them. */ - if (the_acl_type == SMB_ACL_TYPE_ACCESS && *puid == psbuf->st_uid) { + if (the_acl_type == SMB_ACL_TYPE_ACCESS && *puid == psbuf->st_ex_uid) { SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)puid,tagtype); continue; } @@ -2432,7 +2432,7 @@ static canon_ace *canonicalise_acl(struct connection_struct *conn, case SMB_ACL_GROUP_OBJ: /* Get the SID from the owning group. */ sid_copy(&sid, pgroup); - unix_ug.gid = psbuf->st_gid; + unix_ug.gid = psbuf->st_ex_gid; owner_type = GID_ACE; break; case SMB_ACL_GROUP: @@ -2486,7 +2486,7 @@ static canon_ace *canonicalise_acl(struct connection_struct *conn, */ if (!ensure_canon_entry_valid(&l_head, conn->params, - S_ISDIR(psbuf->st_mode), powner, pgroup, + S_ISDIR(psbuf->st_ex_mode), powner, pgroup, psbuf, False)) goto fail; @@ -3097,7 +3097,7 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn, goto done; } - if (S_ISDIR(sbuf->st_mode) && def_acl) { + if (S_ISDIR(sbuf->st_ex_mode) && def_acl) { dir_ace = canonicalise_acl(conn, name, def_acl, sbuf, &global_sid_Creator_Owner, @@ -3181,7 +3181,7 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn, uint32_t acc = map_canon_ace_perms(SNUM(conn), &nt_acl_type, ace->perms, - S_ISDIR(sbuf->st_mode)); + S_ISDIR(sbuf->st_ex_mode)); init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, @@ -3202,7 +3202,7 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn, uint32_t acc = map_canon_ace_perms(SNUM(conn), &nt_acl_type, ace->perms, - S_ISDIR(sbuf->st_mode)); + S_ISDIR(sbuf->st_ex_mode)); init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, @@ -3357,7 +3357,7 @@ NTSTATUS posix_get_nt_acl(struct connection_struct *conn, const char *name, posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name, SMB_ACL_TYPE_ACCESS); /* If it's a directory get the default POSIX ACL. */ - if(S_ISDIR(sbuf.st_mode)) { + if(S_ISDIR(sbuf.st_ex_mode)) { def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name, SMB_ACL_TYPE_DEFAULT); def_acl = free_empty_sys_acl(conn, def_acl); } @@ -3687,7 +3687,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC } /* Save the original element we check against. */ - orig_mode = sbuf.st_mode; + orig_mode = sbuf.st_ex_mode; /* * Unpack the user/group/world id's. @@ -3704,7 +3704,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC * Noticed by Simo. */ - if (((user != (uid_t)-1) && (sbuf.st_uid != user)) || (( grp != (gid_t)-1) && (sbuf.st_gid != grp))) { + if (((user != (uid_t)-1) && (sbuf.st_ex_uid != user)) || (( grp != (gid_t)-1) && (sbuf.st_ex_gid != grp))) { DEBUG(3,("set_nt_acl: chown %s. uid = %u, gid = %u.\n", fsp->fsp_name, (unsigned int)user, (unsigned int)grp )); @@ -3741,7 +3741,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC } /* Save the original element we check against. */ - orig_mode = sbuf.st_mode; + orig_mode = sbuf.st_ex_mode; /* If we successfully chowned, we know we must * be able to set the acl, so do it as root. @@ -3785,7 +3785,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC if (set_acl_as_root) { become_root(); } - ret = set_canon_ace_list(fsp, file_ace_list, False, sbuf.st_gid, &acl_set_support); + ret = set_canon_ace_list(fsp, file_ace_list, False, sbuf.st_ex_gid, &acl_set_support); if (set_acl_as_root) { unbecome_root(); } @@ -3802,7 +3802,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC if (set_acl_as_root) { become_root(); } - ret = set_canon_ace_list(fsp, dir_ace_list, True, sbuf.st_gid, &acl_set_support); + ret = set_canon_ace_list(fsp, dir_ace_list, True, sbuf.st_ex_gid, &acl_set_support); if (set_acl_as_root) { unbecome_root(); } @@ -3827,7 +3827,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC unbecome_root(); } if (sret == -1) { - if (acl_group_override(conn, sbuf.st_gid, fsp->fsp_name)) { + if (acl_group_override(conn, sbuf.st_ex_gid, fsp->fsp_name)) { DEBUG(5,("set_nt_acl: acl group control on and " "current user in file %s primary group. Override delete_def_acl\n", fsp->fsp_name )); @@ -3889,7 +3889,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC unbecome_root(); } if(sret == -1) { - if (acl_group_override(conn, sbuf.st_gid, fsp->fsp_name)) { + if (acl_group_override(conn, sbuf.st_ex_gid, fsp->fsp_name)) { DEBUG(5,("set_nt_acl: acl group control on and " "current user in file %s primary group. Override chmod\n", fsp->fsp_name )); @@ -4285,7 +4285,7 @@ bool set_unix_posix_default_acl(connection_struct *conn, const char *fname, SMB_ { SMB_ACL_T def_acl = NULL; - if (!S_ISDIR(psbuf->st_mode)) { + if (!S_ISDIR(psbuf->st_ex_mode)) { if (num_def_acls) { DEBUG(5,("set_unix_posix_default_acl: Can't set default ACL on non-directory file %s\n", fname )); errno = EISDIR; diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index a21c2cfca1..8657bd6e18 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1022,7 +1022,7 @@ void reply_checkpath(struct smb_request *req) goto path_err; } - if (!S_ISDIR(smb_fname->st.st_mode)) { + if (!S_ISDIR(smb_fname->st.st_ex_mode)) { reply_botherror(req, NT_STATUS_NOT_A_DIRECTORY, ERRDOS, ERRbadpath); goto out; @@ -1135,8 +1135,8 @@ void reply_getatr(struct smb_request *req) } mode = dos_mode(conn, fname, &smb_fname->st); - size = smb_fname->st.st_size; - mtime = smb_fname->st.st_mtime; + size = smb_fname->st.st_ex_size; + mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime); if (mode & aDIR) { size = 0; } @@ -1336,7 +1336,7 @@ void reply_search(struct smb_request *req) char *fname = NULL; SMB_OFF_T size; uint32 mode; - time_t date; + struct timespec date; uint32 dirtype; unsigned int numentries = 0; unsigned int maxentries = 0; @@ -1555,7 +1555,7 @@ void reply_search(struct smb_request *req) fname, size, mode, - date, + convert_timespec_to_time_t(date), !allow_long_path_components)) { reply_nterror(req, NT_STATUS_NO_MEMORY); END_PROFILE(SMBsearch); @@ -1775,9 +1775,9 @@ void reply_open(struct smb_request *req) return; } - size = sbuf.st_size; + size = sbuf.st_ex_size; fattr = dos_mode(conn,fsp->fsp_name,&sbuf); - mtime = sbuf.st_mtime; + mtime = convert_timespec_to_time_t(sbuf.st_ex_mtime); if (fattr & aDIR) { DEBUG(3,("attempt to open a directory %s\n",fsp->fsp_name)); @@ -1939,11 +1939,11 @@ void reply_open_and_X(struct smb_request *req) END_PROFILE(SMBopenX); return; } - sbuf.st_size = SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&sbuf); + sbuf.st_ex_size = SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&sbuf); } fattr = dos_mode(conn,fsp->fsp_name,&sbuf); - mtime = sbuf.st_mtime; + mtime = convert_timespec_to_time_t(sbuf.st_ex_mtime); if (fattr & aDIR) { close_file(req, fsp, ERROR_CLOSE); reply_doserror(req, ERRDOS, ERRnoaccess); @@ -1992,7 +1992,7 @@ void reply_open_and_X(struct smb_request *req) } else { srv_put_dos_date3((char *)req->outbuf,smb_vwv4,mtime); } - SIVAL(req->outbuf,smb_vwv6,(uint32)sbuf.st_size); + SIVAL(req->outbuf,smb_vwv6,(uint32)sbuf.st_ex_size); SSVAL(req->outbuf,smb_vwv8,GET_OPENX_MODE(deny_mode)); SSVAL(req->outbuf,smb_vwv11,smb_action); @@ -2124,7 +2124,7 @@ void reply_mknew(struct smb_request *req) return; } - ft.atime = get_atimespec(&sbuf); /* atime. */ + ft.atime = sbuf.st_ex_atime; /* atime. */ status = smb_set_file_time(conn, fsp, fsp->fsp_name, &sbuf, &ft, true); if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBcreate); @@ -2306,7 +2306,7 @@ void reply_ctemp(struct smb_request *req) DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fsp->fsp_name ) ); DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fsp->fsp_name, - fsp->fh->fd, (unsigned int)smb_fname->st.st_mode)); + fsp->fh->fd, (unsigned int)smb_fname->st.st_ex_mode)); out: TALLOC_FREE(smb_fname); END_PROFILE(SMBctemp); @@ -2331,7 +2331,7 @@ static NTSTATUS can_rename(connection_struct *conn, files_struct *fsp, return NT_STATUS_NO_SUCH_FILE; } - if (S_ISDIR(pst->st_mode)) { + if (S_ISDIR(pst->st_ex_mode)) { if (fsp->posix_open) { return NT_STATUS_OK; } @@ -3104,7 +3104,7 @@ void reply_readbraw(struct smb_request *req) } if (SMB_VFS_FSTAT(fsp, &st) == 0) { - size = st.st_size; + size = st.st_ex_size; } if (startpos >= size) { @@ -3393,8 +3393,8 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req, return; } - if (!S_ISREG(sbuf.st_mode) || (startpos > sbuf.st_size) - || (smb_maxcnt > (sbuf.st_size - startpos))) { + if (!S_ISREG(sbuf.st_ex_mode) || (startpos > sbuf.st_ex_size) + || (smb_maxcnt > (sbuf.st_ex_size - startpos))) { /* * We already know that we would do a short read, so don't * try the sendfile() path. @@ -4442,7 +4442,7 @@ void reply_lseek(struct smb_request *req) return; } - current_pos += sbuf.st_size; + current_pos += sbuf.st_ex_size; if(current_pos < 0) res = SMB_VFS_LSEEK(fsp,0,SEEK_SET); } @@ -5287,7 +5287,7 @@ static bool recursive_rmdir(TALLOC_CTX *ctx, break; } - if(st.st_mode & S_IFDIR) { + if(st.st_ex_mode & S_IFDIR) { if(!recursive_rmdir(ctx, conn, fullname)) { ret = False; break; @@ -5322,12 +5322,12 @@ NTSTATUS rmdir_internals(TALLOC_CTX *ctx, return map_nt_error_from_unix(errno); } - if (S_ISLNK(st.st_mode)) { + if (S_ISLNK(st.st_ex_mode)) { /* Is what it points to a directory ? */ if(SMB_VFS_STAT(conn, directory, &st) != 0) { return map_nt_error_from_unix(errno); } - if (!(S_ISDIR(st.st_mode))) { + if (!(S_ISDIR(st.st_ex_mode))) { return NT_STATUS_NOT_A_DIRECTORY; } ret = SMB_VFS_UNLINK(conn,directory); @@ -5404,7 +5404,7 @@ NTSTATUS rmdir_internals(TALLOC_CTX *ctx, if(SMB_VFS_LSTAT(conn,fullname, &st) != 0) { break; } - if(st.st_mode & S_IFDIR) { + if(st.st_ex_mode & S_IFDIR) { if(!recursive_rmdir(ctx, conn, fullname)) { break; } @@ -6103,7 +6103,7 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, SMB_VFS_STAT(conn, directory, &smb_fname->st); } - if (S_ISDIR(smb_fname->st.st_mode)) { + if (S_ISDIR(smb_fname->st.st_ex_mode)) { create_options |= FILE_DIRECTORY_FILE; } @@ -6229,7 +6229,7 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, create_options = 0; - if (S_ISDIR(smb_fname->st.st_mode)) { + if (S_ISDIR(smb_fname->st.st_ex_mode)) { create_options |= FILE_DIRECTORY_FILE; } @@ -6510,18 +6510,18 @@ NTSTATUS copy_file(TALLOC_CTX *ctx, * Stop the copy from occurring. */ ret = -1; - src_sbuf.st_size = 0; + src_sbuf.st_ex_size = 0; } } - if (src_sbuf.st_size) { - ret = vfs_transfer_file(fsp1, fsp2, src_sbuf.st_size); + if (src_sbuf.st_ex_size) { + ret = vfs_transfer_file(fsp1, fsp2, src_sbuf.st_ex_size); } close_file(NULL, fsp1, NORMAL_CLOSE); /* Ensure the modtime is set correctly on the destination file. */ - set_close_write_time(fsp2, get_mtimespec(&src_sbuf)); + set_close_write_time(fsp2, src_sbuf.st_ex_mtime); /* * As we are opening fsp1 read-only we only expect @@ -6535,7 +6535,7 @@ NTSTATUS copy_file(TALLOC_CTX *ctx, return status; } - if (ret != (SMB_OFF_T)src_sbuf.st_size) { + if (ret != (SMB_OFF_T)src_sbuf.st_ex_size) { return NT_STATUS_DISK_FULL; } @@ -7551,19 +7551,20 @@ void reply_getattrE(struct smb_request *req) reply_outbuf(req, 11, 0); - create_ts = get_create_timespec(&sbuf, - lp_fake_dir_create_times(SNUM(conn))); + create_ts = sbuf.st_ex_btime; srv_put_dos_date2((char *)req->outbuf, smb_vwv0, create_ts.tv_sec); - srv_put_dos_date2((char *)req->outbuf, smb_vwv2, sbuf.st_atime); + srv_put_dos_date2((char *)req->outbuf, smb_vwv2, + convert_timespec_to_time_t(sbuf.st_ex_atime)); /* Should we check pending modtime here ? JRA */ - srv_put_dos_date2((char *)req->outbuf, smb_vwv4, sbuf.st_mtime); + srv_put_dos_date2((char *)req->outbuf, smb_vwv4, + convert_timespec_to_time_t(sbuf.st_ex_mtime)); if (mode & aDIR) { SIVAL(req->outbuf, smb_vwv6, 0); SIVAL(req->outbuf, smb_vwv8, 0); } else { uint32 allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn,fsp, &sbuf); - SIVAL(req->outbuf, smb_vwv6, (uint32)sbuf.st_size); + SIVAL(req->outbuf, smb_vwv6, (uint32)sbuf.st_ex_size); SIVAL(req->outbuf, smb_vwv8, allocation_size); } SSVAL(req->outbuf,smb_vwv10, mode); diff --git a/source3/smbd/service.c b/source3/smbd/service.c index bc07f0b90d..75c19ce131 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -993,8 +993,8 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, I have disabled this chdir check (tridge) */ /* the alternative is just to check the directory exists */ if ((ret = SMB_VFS_STAT(conn, conn->connectpath, &st)) != 0 || - !S_ISDIR(st.st_mode)) { - if (ret == 0 && !S_ISDIR(st.st_mode)) { + !S_ISDIR(st.st_ex_mode)) { + if (ret == 0 && !S_ISDIR(st.st_ex_mode)) { DEBUG(0,("'%s' is not a directory, when connecting to " "[%s]\n", conn->connectpath, lp_servicename(snum))); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 1748cfa0b8..1b92feb434 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -1015,8 +1015,8 @@ static void call_trans2open(connection_struct *conn, size = get_file_size_stat(&sbuf); fattr = dos_mode(conn,fsp->fsp_name,&sbuf); - mtime = sbuf.st_mtime; - inode = sbuf.st_ino; + mtime = convert_timespec_to_time_t(sbuf.st_ex_mtime); + inode = sbuf.st_ex_ino; if (fattr & aDIR) { close_file(req, fsp, ERROR_CLOSE); reply_doserror(req, ERRDOS,ERRnoaccess); @@ -1136,7 +1136,7 @@ static NTSTATUS unix_perms_from_wire( connection_struct *conn, if (!VALID_STAT(*psbuf)) { return NT_STATUS_INVALID_PARAMETER; } else { - *ret_perms = psbuf->st_mode; + *ret_perms = psbuf->st_ex_mode; return NT_STATUS_OK; } } @@ -1207,7 +1207,7 @@ static bool check_msdfs_link(connection_struct *conn, DEBUG(5,("check_msdfs_link: Masquerading msdfs link %s " "as a directory\n", pathname)); - psbuf->st_mode = (psbuf->st_mode & 0xFFF) | S_IFDIR; + psbuf->st_ex_mode = (psbuf->st_ex_mode & 0xFFF) | S_IFDIR; errno = saved_errno; return true; } @@ -1417,10 +1417,9 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx, } allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn,NULL,&sbuf); - mdate_ts = get_mtimespec(&sbuf); - adate_ts = get_atimespec(&sbuf); - create_date_ts = get_create_timespec(&sbuf, - lp_fake_dir_create_times(SNUM(conn))); + mdate_ts = sbuf.st_ex_mtime; + adate_ts = sbuf.st_ex_atime; + create_date_ts = sbuf.st_ex_btime; if (ask_sharemode) { struct timespec write_time_ts; @@ -1737,8 +1736,8 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx, p +=4; } SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */ - SIVAL(p,0,sbuf.st_ino); p += 4; /* FileIndexLow */ - SIVAL(p,0,sbuf.st_dev); p += 4; /* FileIndexHigh */ + SIVAL(p,0,sbuf.st_ex_ino); p += 4; /* FileIndexLow */ + SIVAL(p,0,sbuf.st_ex_dev); p += 4; /* FileIndexHigh */ len = srvstr_push(base_data, flags2, p, fname, PTR_DIFF(end_data, p), STR_TERMINATE_ASCII); @@ -1793,8 +1792,8 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx, } p += 26; SSVAL(p,0,0); p += 2; /* Reserved ? */ - SIVAL(p,0,sbuf.st_ino); p += 4; /* FileIndexLow */ - SIVAL(p,0,sbuf.st_dev); p += 4; /* FileIndexHigh */ + SIVAL(p,0,sbuf.st_ex_ino); p += 4; /* FileIndexLow */ + SIVAL(p,0,sbuf.st_ex_dev); p += 4; /* FileIndexHigh */ len = srvstr_push(base_data, flags2, p, fname, PTR_DIFF(end_data, p), STR_TERMINATE_ASCII); @@ -2654,10 +2653,10 @@ static void call_trans2qfsinfo(connection_struct *conn, sectors_per_unit = bsize/bytes_per_sector; DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \ -cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit, +cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit, (unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree)); - SIVAL(pdata,l1_idFileSystem,st.st_dev); + SIVAL(pdata,l1_idFileSystem,st.st_ex_dev); SIVAL(pdata,l1_cSectorUnit,sectors_per_unit); SIVAL(pdata,l1_cUnit,dsize); SIVAL(pdata,l1_cUnitAvail,dfree); @@ -2686,7 +2685,8 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsi SCVAL(pdata,l2_vol_cch,len); data_len = l2_vol_szVolLabel + len; DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n", - (unsigned)st.st_ctime, len, vname)); + (unsigned)convert_timespec_to_time_t(st.st_ex_ctime), + len, vname)); break; case SMB_QUERY_FS_ATTRIBUTE_INFO: @@ -3461,7 +3461,7 @@ static bool marshall_posix_acl(connection_struct *conn, char *pdata, SMB_STRUCT_ switch (tagtype) { case SMB_ACL_USER_OBJ: SCVAL(pdata,0,SMB_POSIX_ACL_USER_OBJ); - own_grp = (unsigned int)pst->st_uid; + own_grp = (unsigned int)pst->st_ex_uid; SIVAL(pdata,2,own_grp); SIVAL(pdata,6,0); break; @@ -3481,7 +3481,7 @@ static bool marshall_posix_acl(connection_struct *conn, char *pdata, SMB_STRUCT_ } case SMB_ACL_GROUP_OBJ: SCVAL(pdata,0,SMB_POSIX_ACL_GROUP_OBJ); - own_grp = (unsigned int)pst->st_gid; + own_grp = (unsigned int)pst->st_ex_gid; SIVAL(pdata,2,own_grp); SIVAL(pdata,6,0); break; @@ -3530,7 +3530,7 @@ static char *store_file_unix_basic(connection_struct *conn, const SMB_STRUCT_STAT *psbuf) { DEBUG(10,("store_file_unix_basic: SMB_QUERY_FILE_UNIX_BASIC\n")); - DEBUG(4,("store_file_unix_basic: st_mode=%o\n",(int)psbuf->st_mode)); + DEBUG(4,("store_file_unix_basic: st_mode=%o\n",(int)psbuf->st_ex_mode)); SOFF_T(pdata,0,get_file_size_stat(psbuf)); /* File size 64 Bit */ pdata += 8; @@ -3538,38 +3538,38 @@ static char *store_file_unix_basic(connection_struct *conn, SOFF_T(pdata,0,SMB_VFS_GET_ALLOC_SIZE(conn,fsp,psbuf)); /* Number of bytes used on disk - 64 Bit */ pdata += 8; - put_long_date_timespec(pdata,get_ctimespec(psbuf)); /* Change Time 64 Bit */ - put_long_date_timespec(pdata+8,get_atimespec(psbuf)); /* Last access time 64 Bit */ - put_long_date_timespec(pdata+16,get_mtimespec(psbuf)); /* Last modification time 64 Bit */ + put_long_date_timespec(pdata, psbuf->st_ex_ctime); /* Change Time 64 Bit */ + put_long_date_timespec(pdata+8, psbuf->st_ex_atime); /* Last access time 64 Bit */ + put_long_date_timespec(pdata+16, psbuf->st_ex_mtime); /* Last modification time 64 Bit */ pdata += 24; - SIVAL(pdata,0,psbuf->st_uid); /* user id for the owner */ + SIVAL(pdata,0,psbuf->st_ex_uid); /* user id for the owner */ SIVAL(pdata,4,0); pdata += 8; - SIVAL(pdata,0,psbuf->st_gid); /* group id of owner */ + SIVAL(pdata,0,psbuf->st_ex_gid); /* group id of owner */ SIVAL(pdata,4,0); pdata += 8; - SIVAL(pdata,0,unix_filetype(psbuf->st_mode)); + SIVAL(pdata,0,unix_filetype(psbuf->st_ex_mode)); pdata += 4; - SIVAL(pdata,0,unix_dev_major(psbuf->st_rdev)); /* Major device number if type is device */ + SIVAL(pdata,0,unix_dev_major(psbuf->st_ex_rdev)); /* Major device number if type is device */ SIVAL(pdata,4,0); pdata += 8; - SIVAL(pdata,0,unix_dev_minor(psbuf->st_rdev)); /* Minor device number if type is device */ + SIVAL(pdata,0,unix_dev_minor(psbuf->st_ex_rdev)); /* Minor device number if type is device */ SIVAL(pdata,4,0); pdata += 8; - SINO_T_VAL(pdata,0,(SMB_INO_T)psbuf->st_ino); /* inode number */ + SINO_T_VAL(pdata,0,(SMB_INO_T)psbuf->st_ex_ino); /* inode number */ pdata += 8; - SIVAL(pdata,0, unix_perms_to_wire(psbuf->st_mode)); /* Standard UNIX file permissions */ + SIVAL(pdata,0, unix_perms_to_wire(psbuf->st_ex_mode)); /* Standard UNIX file permissions */ SIVAL(pdata,4,0); pdata += 8; - SIVAL(pdata,0,psbuf->st_nlink); /* number of hard links */ + SIVAL(pdata,0,psbuf->st_ex_nlink); /* number of hard links */ SIVAL(pdata,4,0); pdata += 8; @@ -3618,7 +3618,7 @@ static void map_info2_flags_from_sbuf(const SMB_STRUCT_STAT *psbuf, for (i = 0; i < ARRAY_SIZE(info2_flags_map); ++i) { *smb_fmask |= info2_flags_map[i].smb_fflag; - if (psbuf->st_flags & info2_flags_map[i].stat_fflag) { + if (psbuf->st_ex_flags & info2_flags_map[i].stat_fflag) { *smb_fflags |= info2_flags_map[i].smb_fflag; } } @@ -3634,7 +3634,7 @@ static bool map_info2_flags_to_sbuf(const SMB_STRUCT_STAT *psbuf, uint32 max_fmask = 0; int i; - *stat_fflags = psbuf->st_flags; + *stat_fflags = psbuf->st_ex_flags; /* For each flags requested in smb_fmask, check the state of the * corresponding flag in smb_fflags and set or clear the matching @@ -3680,7 +3680,7 @@ static char *store_file_unix_basic_info2(connection_struct *conn, pdata = store_file_unix_basic(conn, pdata, fsp, psbuf); /* Create (birth) time 64 bit */ - put_long_date_timespec(pdata, get_create_timespec(psbuf, False)); + put_long_date_timespec(pdata, psbuf->st_ex_btime); pdata += 8; map_info2_flags_from_sbuf(psbuf, &file_flags, &flags_mask); @@ -4101,7 +4101,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn, if (!mode) mode = FILE_ATTRIBUTE_NORMAL; - nlink = sbuf.st_nlink; + nlink = sbuf.st_ex_nlink; if (nlink && (mode&aDIR)) { nlink = 1; @@ -4195,9 +4195,9 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd dstart = pdata; dend = dstart + data_size - 1; - create_time_ts = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn))); - mtime_ts = get_mtimespec(&sbuf); - atime_ts = get_atimespec(&sbuf); + create_time_ts = sbuf.st_ex_btime; + mtime_ts = sbuf.st_ex_mtime; + atime_ts = sbuf.st_ex_atime; allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&sbuf); @@ -4454,8 +4454,8 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd BasicFileInformationTest. -tpot */ DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n")); - SIVAL(pdata,0,sbuf.st_ino); /* FileIndexLow */ - SIVAL(pdata,4,sbuf.st_dev); /* FileIndexHigh */ + SIVAL(pdata,0,sbuf.st_ex_ino); /* FileIndexLow */ + SIVAL(pdata,4,sbuf.st_ex_dev); /* FileIndexHigh */ data_size = 8; break; @@ -4624,7 +4624,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n")); #ifdef S_ISLNK - if(!S_ISLNK(sbuf.st_mode)) { + if(!S_ISLNK(sbuf.st_ex_mode)) { reply_unixerror(req, ERRSRV, ERRbadlink); return; @@ -4674,7 +4674,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd return; } - if (S_ISDIR(sbuf.st_mode)) { + if (S_ISDIR(sbuf.st_ex_mode)) { if (fsp && fsp->is_directory) { def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT); } else { @@ -4890,7 +4890,7 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx, } /* No links from a directory. */ - if (S_ISDIR(smb_fname->st.st_mode)) { + if (S_ISDIR(smb_fname->st.st_ex_mode)) { status = NT_STATUS_FILE_IS_A_DIRECTORY; goto out; } @@ -4935,12 +4935,12 @@ NTSTATUS smb_set_file_time(connection_struct *conn, /* get some defaults (no modifications) if any info is zero or -1. */ if (null_timespec(ft->atime)) { - ft->atime= get_atimespec(psbuf); + ft->atime= psbuf->st_ex_atime; action &= ~FILE_NOTIFY_CHANGE_LAST_ACCESS; } if (null_timespec(ft->mtime)) { - ft->mtime = get_mtimespec(psbuf); + ft->mtime = psbuf->st_ex_mtime; action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE; } @@ -4964,8 +4964,8 @@ NTSTATUS smb_set_file_time(connection_struct *conn, */ { - struct timespec mts = get_mtimespec(psbuf); - struct timespec ats = get_atimespec(psbuf); + struct timespec mts = psbuf->st_ex_mtime; + struct timespec ats = psbuf->st_ex_atime; if ((timespec_compare(&ft->atime, &ats) == 0) && (timespec_compare(&ft->mtime, &mts) == 0)) { return NT_STATUS_OK; @@ -5037,7 +5037,7 @@ static NTSTATUS smb_set_file_dosmode(connection_struct *conn, } if (dosmode) { - if (S_ISDIR(psbuf->st_mode)) { + if (S_ISDIR(psbuf->st_ex_mode)) { dosmode |= aDIR; } else { dosmode &= ~aDIR; @@ -6099,7 +6099,7 @@ static NTSTATUS smb_set_file_unix_basic(connection_struct *conn, raw_unixmode = IVAL(pdata,84); if (VALID_STAT(*psbuf)) { - if (S_ISDIR(psbuf->st_mode)) { + if (S_ISDIR(psbuf->st_ex_mode)) { ptype = PERM_EXISTING_DIR; } else { ptype = PERM_EXISTING_FILE; @@ -6136,8 +6136,8 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", /* Ensure we don't try and change anything else. */ raw_unixmode = SMB_MODE_NO_CHANGE; size = get_file_size_stat(psbuf); - ft.atime = get_atimespec(psbuf); - ft.mtime = get_mtimespec(psbuf); + ft.atime = psbuf->st_ex_atime; + ft.mtime = psbuf->st_ex_mtime; /* * We continue here as we might want to change the * owner uid/gid. @@ -6171,13 +6171,13 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", * Deal with the UNIX specific uid set. */ - if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (psbuf->st_uid != set_owner)) { + if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (psbuf->st_ex_uid != set_owner)) { int ret; DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC changing owner %u for path %s\n", (unsigned int)set_owner, fname )); - if (S_ISLNK(psbuf->st_mode)) { + if (S_ISLNK(psbuf->st_ex_mode)) { ret = SMB_VFS_LCHOWN(conn, fname, set_owner, (gid_t)-1); } else { ret = SMB_VFS_CHOWN(conn, fname, set_owner, (gid_t)-1); @@ -6196,7 +6196,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", * Deal with the UNIX specific gid set. */ - if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (psbuf->st_gid != set_grp)) { + if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (psbuf->st_ex_gid != set_grp)) { DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n", (unsigned int)set_owner, fname )); if (SMB_VFS_CHOWN(conn, fname, (uid_t)-1, set_grp) != 0) { diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index f219e5554c..0f70669772 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -353,7 +353,7 @@ bool vfs_directory_exist(connection_struct *conn, const char *dname, SMB_STRUCT_ if (SMB_VFS_STAT(conn,dname,st) != 0) return(False); - ret = S_ISDIR(st->st_mode); + ret = S_ISDIR(st->st_ex_mode); if(!ret) errno = ENOTDIR; @@ -393,7 +393,7 @@ bool vfs_file_exist(connection_struct *conn, const char *fname,SMB_STRUCT_STAT * if (SMB_VFS_STAT(conn,fname,sbuf) == -1) return False; - return(S_ISREG(sbuf->st_mode)); + return(S_ISREG(sbuf->st_ex_mode)); } /**************************************************************************** @@ -542,14 +542,14 @@ int vfs_allocate_file_space(files_struct *fsp, uint64_t len) if (ret == -1) return ret; - if (len == (uint64_t)st.st_size) + if (len == (uint64_t)st.st_ex_size) return 0; - if (len < (uint64_t)st.st_size) { + if (len < (uint64_t)st.st_ex_size) { /* Shrink - use ftruncate. */ DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current size %.0f\n", - fsp->fsp_name, (double)st.st_size )); + fsp->fsp_name, (double)st.st_ex_size )); contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK); @@ -571,7 +571,7 @@ int vfs_allocate_file_space(files_struct *fsp, uint64_t len) if (!lp_strict_allocate(SNUM(fsp->conn))) return 0; - len -= st.st_size; + len -= st.st_ex_size; len /= 1024; /* Len is now number of 1k blocks needed. */ space_avail = get_dfree_info(conn,fsp->fsp_name,False,&bsize,&dfree,&dsize); if (space_avail == (uint64_t)-1) { @@ -579,7 +579,7 @@ int vfs_allocate_file_space(files_struct *fsp, uint64_t len) } DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, needed blocks = %.0f, space avail = %.0f\n", - fsp->fsp_name, (double)st.st_size, (double)len, (double)space_avail )); + fsp->fsp_name, (double)st.st_ex_size, (double)len, (double)space_avail )); if (len > space_avail) { errno = ENOSPC; @@ -639,12 +639,12 @@ int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len) return ret; } - if (len <= st.st_size) { + if (len <= st.st_ex_size) { return 0; } DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to len %.0f (%.0f bytes)\n", - fsp->fsp_name, (double)st.st_size, (double)len, (double)(len - st.st_size))); + fsp->fsp_name, (double)st.st_ex_size, (double)len, (double)(len - st.st_ex_size))); contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE); @@ -659,8 +659,8 @@ int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len) } } - offset = st.st_size; - num_to_write = len - st.st_size; + offset = st.st_ex_size; + num_to_write = len - st.st_ex_size; total = 0; while (total < num_to_write) { @@ -816,8 +816,8 @@ char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn) && (cache_value.data[cache_value.length-1] == '\0')); if ((SMB_VFS_STAT(conn, (char *)cache_value.data, &st2) == 0) - && (st.st_dev == st2.st_dev) && (st.st_ino == st2.st_ino) - && (S_ISDIR(st.st_mode))) { + && (st.st_ex_dev == st2.st_ex_dev) && (st.st_ex_ino == st2.st_ex_ino) + && (S_ISDIR(st.st_ex_mode))) { /* * Ok, we're done */ @@ -973,7 +973,7 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname) if (!lp_symlinks(SNUM(conn))) { SMB_STRUCT_STAT statbuf; if ( (SMB_VFS_LSTAT(conn,fname,&statbuf) != -1) && - (S_ISLNK(statbuf.st_mode)) ) { + (S_ISLNK(statbuf.st_ex_mode)) ) { if (free_resolved_name) { SAFE_FREE(resolved_name); } diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c index 80ee3ec0e8..1664f9a94d 100644 --- a/source3/torture/cmd_vfs.c +++ b/source3/torture/cmd_vfs.c @@ -157,31 +157,35 @@ static NTSTATUS cmd_readdir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc printf("readdir: %s\n", dent->d_name); if (VALID_STAT(st)) { + time_t tmp_time; printf(" stat available"); - if (S_ISREG(st.st_mode)) printf(" Regular File\n"); - else if (S_ISDIR(st.st_mode)) printf(" Directory\n"); - else if (S_ISCHR(st.st_mode)) printf(" Character Device\n"); - else if (S_ISBLK(st.st_mode)) printf(" Block Device\n"); - else if (S_ISFIFO(st.st_mode)) printf(" Fifo\n"); - else if (S_ISLNK(st.st_mode)) printf(" Symbolic Link\n"); - else if (S_ISSOCK(st.st_mode)) printf(" Socket\n"); - printf(" Size: %10u", (unsigned int)st.st_size); + if (S_ISREG(st.st_ex_mode)) printf(" Regular File\n"); + else if (S_ISDIR(st.st_ex_mode)) printf(" Directory\n"); + else if (S_ISCHR(st.st_ex_mode)) printf(" Character Device\n"); + else if (S_ISBLK(st.st_ex_mode)) printf(" Block Device\n"); + else if (S_ISFIFO(st.st_ex_mode)) printf(" Fifo\n"); + else if (S_ISLNK(st.st_ex_mode)) printf(" Symbolic Link\n"); + else if (S_ISSOCK(st.st_ex_mode)) printf(" Socket\n"); + printf(" Size: %10u", (unsigned int)st.st_ex_size); #ifdef HAVE_STAT_ST_BLOCKS - printf(" Blocks: %9u", (unsigned int)st.st_blocks); + printf(" Blocks: %9u", (unsigned int)st.st_ex_blocks); #endif #ifdef HAVE_STAT_ST_BLKSIZE - printf(" IO Block: %u\n", (unsigned int)st.st_blksize); + printf(" IO Block: %u\n", (unsigned int)st.st_ex_blksize); #endif - printf(" Device: 0x%10x", (unsigned int)st.st_dev); - printf(" Inode: %10u", (unsigned int)st.st_ino); - printf(" Links: %10u\n", (unsigned int)st.st_nlink); - printf(" Access: %05o", (int)((st.st_mode) & 007777)); + printf(" Device: 0x%10x", (unsigned int)st.st_ex_dev); + printf(" Inode: %10u", (unsigned int)st.st_ex_ino); + printf(" Links: %10u\n", (unsigned int)st.st_ex_nlink); + printf(" Access: %05o", (int)((st.st_ex_mode) & 007777)); printf(" Uid: %5lu Gid: %5lu\n", - (unsigned long)st.st_uid, - (unsigned long)st.st_gid); - printf(" Access: %s", ctime(&(st.st_atime))); - printf(" Modify: %s", ctime(&(st.st_mtime))); - printf(" Change: %s", ctime(&(st.st_ctime))); + (unsigned long)st.st_ex_uid, + (unsigned long)st.st_ex_gid); + tmp_time = convert_timespec_to_time_t(st.st_ex_atime); + printf(" Access: %s", ctime(&tmp_time)); + tmp_time = convert_timespec_to_time_t(st.st_ex_mtime); + printf(" Modify: %s", ctime(&tmp_time)); + tmp_time = convert_timespec_to_time_t(st.st_ex_ctime); + printf(" Change: %s", ctime(&tmp_time)); } return NT_STATUS_OK; @@ -540,6 +544,7 @@ static NTSTATUS cmd_stat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c struct passwd *pwd = NULL; struct group *grp = NULL; SMB_STRUCT_STAT st; + time_t tmp_time; if (argc != 2) { printf("Usage: stat \n"); @@ -552,38 +557,41 @@ static NTSTATUS cmd_stat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c return NT_STATUS_UNSUCCESSFUL; } - pwd = sys_getpwuid(st.st_uid); + pwd = sys_getpwuid(st.st_ex_uid); if (pwd != NULL) user = pwd->pw_name; else user = null_string; - grp = sys_getgrgid(st.st_gid); + grp = sys_getgrgid(st.st_ex_gid); if (grp != NULL) group = grp->gr_name; else group = null_string; printf("stat: ok\n"); printf(" File: %s", argv[1]); - if (S_ISREG(st.st_mode)) printf(" Regular File\n"); - else if (S_ISDIR(st.st_mode)) printf(" Directory\n"); - else if (S_ISCHR(st.st_mode)) printf(" Character Device\n"); - else if (S_ISBLK(st.st_mode)) printf(" Block Device\n"); - else if (S_ISFIFO(st.st_mode)) printf(" Fifo\n"); - else if (S_ISLNK(st.st_mode)) printf(" Symbolic Link\n"); - else if (S_ISSOCK(st.st_mode)) printf(" Socket\n"); - printf(" Size: %10u", (unsigned int)st.st_size); + if (S_ISREG(st.st_ex_mode)) printf(" Regular File\n"); + else if (S_ISDIR(st.st_ex_mode)) printf(" Directory\n"); + else if (S_ISCHR(st.st_ex_mode)) printf(" Character Device\n"); + else if (S_ISBLK(st.st_ex_mode)) printf(" Block Device\n"); + else if (S_ISFIFO(st.st_ex_mode)) printf(" Fifo\n"); + else if (S_ISLNK(st.st_ex_mode)) printf(" Symbolic Link\n"); + else if (S_ISSOCK(st.st_ex_mode)) printf(" Socket\n"); + printf(" Size: %10u", (unsigned int)st.st_ex_size); #ifdef HAVE_STAT_ST_BLOCKS - printf(" Blocks: %9u", (unsigned int)st.st_blocks); + printf(" Blocks: %9u", (unsigned int)st.st_ex_blocks); #endif #ifdef HAVE_STAT_ST_BLKSIZE - printf(" IO Block: %u\n", (unsigned int)st.st_blksize); + printf(" IO Block: %u\n", (unsigned int)st.st_ex_blksize); #endif - printf(" Device: 0x%10x", (unsigned int)st.st_dev); - printf(" Inode: %10u", (unsigned int)st.st_ino); - printf(" Links: %10u\n", (unsigned int)st.st_nlink); - printf(" Access: %05o", (int)((st.st_mode) & 007777)); - printf(" Uid: %5lu/%.16s Gid: %5lu/%.16s\n", (unsigned long)st.st_uid, user, - (unsigned long)st.st_gid, group); - printf(" Access: %s", ctime(&(st.st_atime))); - printf(" Modify: %s", ctime(&(st.st_mtime))); - printf(" Change: %s", ctime(&(st.st_ctime))); + printf(" Device: 0x%10x", (unsigned int)st.st_ex_dev); + printf(" Inode: %10u", (unsigned int)st.st_ex_ino); + printf(" Links: %10u\n", (unsigned int)st.st_ex_nlink); + printf(" Access: %05o", (int)((st.st_ex_mode) & 007777)); + printf(" Uid: %5lu/%.16s Gid: %5lu/%.16s\n", (unsigned long)st.st_ex_uid, user, + (unsigned long)st.st_ex_gid, group); + tmp_time = convert_timespec_to_time_t(st.st_ex_atime); + printf(" Access: %s", ctime(&tmp_time)); + tmp_time = convert_timespec_to_time_t(st.st_ex_mtime); + printf(" Modify: %s", ctime(&tmp_time)); + tmp_time = convert_timespec_to_time_t(st.st_ex_ctime); + printf(" Change: %s", ctime(&tmp_time)); return NT_STATUS_OK; } @@ -597,6 +605,7 @@ static NTSTATUS cmd_fstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, struct passwd *pwd = NULL; struct group *grp = NULL; SMB_STRUCT_STAT st; + time_t tmp_time; if (argc != 2) { printf("Usage: fstat \n"); @@ -619,37 +628,40 @@ static NTSTATUS cmd_fstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, return NT_STATUS_UNSUCCESSFUL; } - pwd = sys_getpwuid(st.st_uid); + pwd = sys_getpwuid(st.st_ex_uid); if (pwd != NULL) user = pwd->pw_name; else user = null_string; - grp = sys_getgrgid(st.st_gid); + grp = sys_getgrgid(st.st_ex_gid); if (grp != NULL) group = grp->gr_name; else group = null_string; printf("fstat: ok\n"); - if (S_ISREG(st.st_mode)) printf(" Regular File\n"); - else if (S_ISDIR(st.st_mode)) printf(" Directory\n"); - else if (S_ISCHR(st.st_mode)) printf(" Character Device\n"); - else if (S_ISBLK(st.st_mode)) printf(" Block Device\n"); - else if (S_ISFIFO(st.st_mode)) printf(" Fifo\n"); - else if (S_ISLNK(st.st_mode)) printf(" Symbolic Link\n"); - else if (S_ISSOCK(st.st_mode)) printf(" Socket\n"); - printf(" Size: %10u", (unsigned int)st.st_size); + if (S_ISREG(st.st_ex_mode)) printf(" Regular File\n"); + else if (S_ISDIR(st.st_ex_mode)) printf(" Directory\n"); + else if (S_ISCHR(st.st_ex_mode)) printf(" Character Device\n"); + else if (S_ISBLK(st.st_ex_mode)) printf(" Block Device\n"); + else if (S_ISFIFO(st.st_ex_mode)) printf(" Fifo\n"); + else if (S_ISLNK(st.st_ex_mode)) printf(" Symbolic Link\n"); + else if (S_ISSOCK(st.st_ex_mode)) printf(" Socket\n"); + printf(" Size: %10u", (unsigned int)st.st_ex_size); #ifdef HAVE_STAT_ST_BLOCKS - printf(" Blocks: %9u", (unsigned int)st.st_blocks); + printf(" Blocks: %9u", (unsigned int)st.st_ex_blocks); #endif #ifdef HAVE_STAT_ST_BLKSIZE - printf(" IO Block: %u\n", (unsigned int)st.st_blksize); + printf(" IO Block: %u\n", (unsigned int)st.st_ex_blksize); #endif - printf(" Device: 0x%10x", (unsigned int)st.st_dev); - printf(" Inode: %10u", (unsigned int)st.st_ino); - printf(" Links: %10u\n", (unsigned int)st.st_nlink); - printf(" Access: %05o", (int)((st.st_mode) & 007777)); - printf(" Uid: %5lu/%.16s Gid: %5lu/%.16s\n", (unsigned long)st.st_uid, user, - (unsigned long)st.st_gid, group); - printf(" Access: %s", ctime(&(st.st_atime))); - printf(" Modify: %s", ctime(&(st.st_mtime))); - printf(" Change: %s", ctime(&(st.st_ctime))); + printf(" Device: 0x%10x", (unsigned int)st.st_ex_dev); + printf(" Inode: %10u", (unsigned int)st.st_ex_ino); + printf(" Links: %10u\n", (unsigned int)st.st_ex_nlink); + printf(" Access: %05o", (int)((st.st_ex_mode) & 007777)); + printf(" Uid: %5lu/%.16s Gid: %5lu/%.16s\n", (unsigned long)st.st_ex_uid, user, + (unsigned long)st.st_ex_gid, group); + tmp_time = convert_timespec_to_time_t(st.st_ex_atime); + printf(" Access: %s", ctime(&tmp_time)); + tmp_time = convert_timespec_to_time_t(st.st_ex_mtime); + printf(" Modify: %s", ctime(&tmp_time)); + tmp_time = convert_timespec_to_time_t(st.st_ex_ctime); + printf(" Change: %s", ctime(&tmp_time)); return NT_STATUS_OK; } @@ -662,6 +674,7 @@ static NTSTATUS cmd_lstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, struct passwd *pwd = NULL; struct group *grp = NULL; SMB_STRUCT_STAT st; + time_t tmp_time; if (argc != 2) { printf("Usage: lstat \n"); @@ -673,37 +686,40 @@ static NTSTATUS cmd_lstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, return NT_STATUS_UNSUCCESSFUL; } - pwd = sys_getpwuid(st.st_uid); + pwd = sys_getpwuid(st.st_ex_uid); if (pwd != NULL) user = pwd->pw_name; else user = null_string; - grp = sys_getgrgid(st.st_gid); + grp = sys_getgrgid(st.st_ex_gid); if (grp != NULL) group = grp->gr_name; else group = null_string; printf("lstat: ok\n"); - if (S_ISREG(st.st_mode)) printf(" Regular File\n"); - else if (S_ISDIR(st.st_mode)) printf(" Directory\n"); - else if (S_ISCHR(st.st_mode)) printf(" Character Device\n"); - else if (S_ISBLK(st.st_mode)) printf(" Block Device\n"); - else if (S_ISFIFO(st.st_mode)) printf(" Fifo\n"); - else if (S_ISLNK(st.st_mode)) printf(" Symbolic Link\n"); - else if (S_ISSOCK(st.st_mode)) printf(" Socket\n"); - printf(" Size: %10u", (unsigned int)st.st_size); + if (S_ISREG(st.st_ex_mode)) printf(" Regular File\n"); + else if (S_ISDIR(st.st_ex_mode)) printf(" Directory\n"); + else if (S_ISCHR(st.st_ex_mode)) printf(" Character Device\n"); + else if (S_ISBLK(st.st_ex_mode)) printf(" Block Device\n"); + else if (S_ISFIFO(st.st_ex_mode)) printf(" Fifo\n"); + else if (S_ISLNK(st.st_ex_mode)) printf(" Symbolic Link\n"); + else if (S_ISSOCK(st.st_ex_mode)) printf(" Socket\n"); + printf(" Size: %10u", (unsigned int)st.st_ex_size); #ifdef HAVE_STAT_ST_BLOCKS - printf(" Blocks: %9u", (unsigned int)st.st_blocks); + printf(" Blocks: %9u", (unsigned int)st.st_ex_blocks); #endif #ifdef HAVE_STAT_ST_BLKSIZE - printf(" IO Block: %u\n", (unsigned int)st.st_blksize); + printf(" IO Block: %u\n", (unsigned int)st.st_ex_blksize); #endif - printf(" Device: 0x%10x", (unsigned int)st.st_dev); - printf(" Inode: %10u", (unsigned int)st.st_ino); - printf(" Links: %10u\n", (unsigned int)st.st_nlink); - printf(" Access: %05o", (int)((st.st_mode) & 007777)); - printf(" Uid: %5lu/%.16s Gid: %5lu/%.16s\n", (unsigned long)st.st_uid, user, - (unsigned long)st.st_gid, group); - printf(" Access: %s", ctime(&(st.st_atime))); - printf(" Modify: %s", ctime(&(st.st_mtime))); - printf(" Change: %s", ctime(&(st.st_ctime))); + printf(" Device: 0x%10x", (unsigned int)st.st_ex_dev); + printf(" Inode: %10u", (unsigned int)st.st_ex_ino); + printf(" Links: %10u\n", (unsigned int)st.st_ex_nlink); + printf(" Access: %05o", (int)((st.st_ex_mode) & 007777)); + printf(" Uid: %5lu/%.16s Gid: %5lu/%.16s\n", (unsigned long)st.st_ex_uid, user, + (unsigned long)st.st_ex_gid, group); + tmp_time = convert_timespec_to_time_t(st.st_ex_atime); + printf(" Access: %s", ctime(&tmp_time)); + tmp_time = convert_timespec_to_time_t(st.st_ex_mtime); + printf(" Modify: %s", ctime(&tmp_time)); + tmp_time = convert_timespec_to_time_t(st.st_ex_ctime); + printf(" Change: %s", ctime(&tmp_time)); return NT_STATUS_OK; } diff --git a/source3/utils/net_conf.c b/source3/utils/net_conf.c index 69a41e30d9..6b0f70adfa 100644 --- a/source3/utils/net_conf.c +++ b/source3/utils/net_conf.c @@ -662,7 +662,7 @@ static int net_conf_addshare(struct net_context *c, goto done; } - if (!S_ISDIR(sbuf.st_mode)) { + if (!S_ISDIR(sbuf.st_ex_mode)) { d_fprintf(stderr, "ERROR: path '%s' is not a directory.\n", path); diff --git a/source3/utils/net_usershare.c b/source3/utils/net_usershare.c index dadb88303b..992a03d813 100644 --- a/source3/utils/net_usershare.c +++ b/source3/utils/net_usershare.c @@ -250,13 +250,13 @@ static int get_share_list(TALLOC_CTX *ctx, const char *wcard, bool only_ours) continue; } - if (!S_ISREG(sbuf.st_mode)) { + if (!S_ISREG(sbuf.st_ex_mode)) { d_fprintf(stderr, "get_share_list: file %s is not a regular file. Ignoring.\n", path ); continue; } - if (only_ours && sbuf.st_uid != myuid) { + if (only_ours && sbuf.st_ex_uid != myuid) { continue; } @@ -364,7 +364,7 @@ static int info_fn(struct file_list *fl, void *priv) return -1; } - if (!S_ISREG(sbuf.st_mode)) { + if (!S_ISREG(sbuf.st_ex_mode)) { d_fprintf(stderr, "info_fn: file %s is not a regular file. Ignoring.\n", basepath ); close(fd); @@ -574,7 +574,7 @@ static int count_num_usershares(void) continue; } - if (!S_ISREG(sbuf.st_mode)) { + if (!S_ISREG(sbuf.st_ex_mode)) { d_fprintf(stderr, "count_num_usershares: file %s is not a regular file. Ignoring.\n", path ); continue; @@ -738,7 +738,7 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) return -1; } - if (!S_ISDIR(sbuf.st_mode)) { + if (!S_ISDIR(sbuf.st_ex_mode)) { d_fprintf(stderr, "net usershare add: path %s is not a directory.\n", us_path ); TALLOC_FREE(ctx); @@ -749,7 +749,7 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) /* If we're not root, check if we're restricted to sharing out directories that we own only. */ - if ((myeuid != 0) && lp_usershare_owner_only() && (myeuid != sbuf.st_uid)) { + if ((myeuid != 0) && lp_usershare_owner_only() && (myeuid != sbuf.st_ex_uid)) { d_fprintf(stderr, "net usershare add: cannot share path %s as " "we are restricted to only sharing directories we own.\n" "\tAsk the administrator to add the line \"usershare owner only = false\" \n" @@ -887,7 +887,7 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv) return -1; } - if (!S_ISREG(sbuf.st_mode) || sbuf.st_dev != lsbuf.st_dev || sbuf.st_ino != lsbuf.st_ino) { + if (!S_ISREG(sbuf.st_ex_mode) || sbuf.st_ex_dev != lsbuf.st_ex_dev || sbuf.st_ex_ino != lsbuf.st_ex_ino) { d_fprintf(stderr, "net usershare add: tmp file %s is not a regular file ?\n", full_path_tmp ); TALLOC_FREE(ctx); diff --git a/source3/utils/testparm.c b/source3/utils/testparm.c index e8458fda1b..519eb6954a 100644 --- a/source3/utils/testparm.c +++ b/source3/utils/testparm.c @@ -60,7 +60,7 @@ cannot be set in the smb.conf file. nmbd will abort with this setting.\n"); fprintf(stderr, "ERROR: lock directory %s does not exist\n", lp_lockdir()); ret = 1; - } else if ((st.st_mode & 0777) != 0755) { + } else if ((st.st_ex_mode & 0777) != 0755) { fprintf(stderr, "WARNING: lock directory %s should have permissions 0755 for browsing to work\n", lp_lockdir()); ret = 1; @@ -70,7 +70,7 @@ cannot be set in the smb.conf file. nmbd will abort with this setting.\n"); fprintf(stderr, "ERROR: state directory %s does not exist\n", lp_statedir()); ret = 1; - } else if ((st.st_mode & 0777) != 0755) { + } else if ((st.st_ex_mode & 0777) != 0755) { fprintf(stderr, "WARNING: state directory %s should have permissions 0755 for browsing to work\n", lp_statedir()); ret = 1; @@ -80,7 +80,7 @@ cannot be set in the smb.conf file. nmbd will abort with this setting.\n"); fprintf(stderr, "ERROR: cache directory %s does not exist\n", lp_cachedir()); ret = 1; - } else if ((st.st_mode & 0777) != 0755) { + } else if ((st.st_ex_mode & 0777) != 0755) { fprintf(stderr, "WARNING: cache directory %s should have permissions 0755 for browsing to work\n", lp_cachedir()); ret = 1; diff --git a/source3/web/cgi.c b/source3/web/cgi.c index 261d4366bf..a31943fa8d 100644 --- a/source3/web/cgi.c +++ b/source3/web/cgi.c @@ -448,16 +448,16 @@ static void cgi_download(char *file) "The requested file was not found"); } - if (S_ISDIR(st.st_mode)) + if (S_ISDIR(st.st_ex_mode)) { snprintf(buf, sizeof(buf), "%s/index.html", file); - if (!file_exist_stat(buf, &st) || !S_ISREG(st.st_mode)) + if (!file_exist_stat(buf, &st) || !S_ISREG(st.st_ex_mode)) { cgi_setup_error("404 File Not Found","", "The requested file was not found"); } } - else if (S_ISREG(st.st_mode)) + else if (S_ISREG(st.st_ex_mode)) { snprintf(buf, sizeof(buf), "%s", file); } @@ -496,7 +496,7 @@ static void cgi_download(char *file) printf("Content-Language: %s\r\n", lang); } - printf("Content-Length: %d\r\n\r\n", (int)st.st_size); + printf("Content-Length: %d\r\n\r\n", (int)st.st_ex_size); while ((l=read(fd,buf,sizeof(buf)))>0) { if (fwrite(buf, 1, l, stdout) != l) { break; -- cgit From 447515efaabb408a1deead64d39236c6c8e9aaea Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 26 May 2009 21:07:08 +0200 Subject: Fix some nonempty blank lines --- source3/smbd/trans2.c | 55 +++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 1b92feb434..ef7f617010 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -2578,7 +2578,7 @@ static void call_trans2qfsinfo(connection_struct *conn, int snum = SNUM(conn); char *fstype = lp_fstype(SNUM(conn)); uint32 additional_flags = 0; - + if (total_params < 2) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); return; @@ -2849,13 +2849,13 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned */ files_struct fsp; SMB_NTQUOTA_STRUCT quotas; - + ZERO_STRUCT(fsp); ZERO_STRUCT(quotas); - + fsp.conn = conn; fsp.fnum = -1; - + /* access check */ if (conn->server_info->utok.uid != 0) { DEBUG(0,("set_user_quota: access_denied " @@ -2865,7 +2865,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned reply_doserror(req, ERRDOS, ERRnoaccess); return; } - + if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) { DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn)))); reply_doserror(req, ERRSRV, ERRerror); @@ -2875,25 +2875,25 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned data_len = 48; DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn)))); - + /* Unknown1 24 NULL bytes*/ SBIG_UINT(pdata,0,(uint64_t)0); SBIG_UINT(pdata,8,(uint64_t)0); SBIG_UINT(pdata,16,(uint64_t)0); - + /* Default Soft Quota 8 bytes */ SBIG_UINT(pdata,24,quotas.softlim); /* Default Hard Quota 8 bytes */ SBIG_UINT(pdata,32,quotas.hardlim); - + /* Quota flag 2 bytes */ SSVAL(pdata,40,quotas.qflags); - + /* Unknown3 6 NULL bytes */ SSVAL(pdata,42,0); SIVAL(pdata,44,0); - + break; } #endif /* HAVE_SYS_QUOTAS */ @@ -3300,7 +3300,7 @@ cap_low = 0x%x, cap_high = 0x%x\n", { files_struct *fsp = NULL; SMB_NTQUOTA_STRUCT quotas; - + ZERO_STRUCT(quotas); /* access check */ @@ -3335,9 +3335,9 @@ cap_low = 0x%x, cap_high = 0x%x\n", NT_STATUS_INVALID_PARAMETER); return; } - + /* unknown_1 24 NULL bytes in pdata*/ - + /* the soft quotas 8 bytes (uint64_t)*/ quotas.softlim = (uint64_t)IVAL(pdata,24); #ifdef LARGE_SMB_OFF_T @@ -3353,7 +3353,7 @@ cap_low = 0x%x, cap_high = 0x%x\n", return; } #endif /* LARGE_SMB_OFF_T */ - + /* the hard quotas 8 bytes (uint64_t)*/ quotas.hardlim = (uint64_t)IVAL(pdata,32); #ifdef LARGE_SMB_OFF_T @@ -3369,19 +3369,19 @@ cap_low = 0x%x, cap_high = 0x%x\n", return; } #endif /* LARGE_SMB_OFF_T */ - + /* quota_flags 2 bytes **/ quotas.qflags = SVAL(pdata,40); - + /* unknown_2 6 NULL bytes follow*/ - + /* now set the quotas */ if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, "as)!=0) { DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn)))); reply_doserror(req, ERRSRV, ERRerror); return; } - + break; } default: @@ -3564,7 +3564,7 @@ static char *store_file_unix_basic(connection_struct *conn, SINO_T_VAL(pdata,0,(SMB_INO_T)psbuf->st_ex_ino); /* inode number */ pdata += 8; - + SIVAL(pdata,0, unix_perms_to_wire(psbuf->st_ex_mode)); /* Standard UNIX file permissions */ SIVAL(pdata,4,0); pdata += 8; @@ -5035,7 +5035,7 @@ static NTSTATUS smb_set_file_dosmode(connection_struct *conn, fname = fsp->fsp_name; } } - + if (dosmode) { if (S_ISDIR(psbuf->st_ex_mode)) { dosmode |= aDIR; @@ -7123,7 +7123,6 @@ static void call_trans2setfilepathinfo(connection_struct *conn, return; } - if (!NT_STATUS_IS_OK(status)) { if (open_was_deferred(req->mid)) { /* We have re-scheduled this call. */ @@ -7150,7 +7149,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn, SSVAL(params,0,0); send_trans2_replies(conn, req, params, 2, *ppdata, data_return_size, max_data_bytes); - + return; } @@ -7253,7 +7252,7 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req, reply_nterror(req, status); return; } - + /* Try and set any given EA. */ if (ea_list) { status = set_ea(conn, NULL, directory, ea_list); @@ -7274,7 +7273,7 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req, SSVAL(params,0,0); send_trans2_replies(conn, req, params, 2, *ppdata, 0, max_data_bytes); - + return; } @@ -7327,7 +7326,7 @@ static void call_trans2findnotifyfirst(connection_struct *conn, fnf_handle = 257; send_trans2_replies(conn, req, params, 6, *ppdata, 0, max_data_bytes); - + return; } @@ -7358,7 +7357,7 @@ static void call_trans2findnotifynext(connection_struct *conn, SSVAL(params,2,0); /* No EA errors */ send_trans2_replies(conn, req, params, 4, *ppdata, 0, max_data_bytes); - + return; } @@ -7508,7 +7507,7 @@ void reply_findnclose(struct smb_request *req) END_PROFILE(SMBfindnclose); return; } - + dptr_num = SVAL(req->vwv+0, 0); DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num)); @@ -7928,7 +7927,7 @@ void reply_transs2(struct smb_request *req) state->received_param += pcnt; state->received_data += dcnt; - + if ((state->received_data > state->total_data) || (state->received_param > state->total_param)) goto bad_param; -- cgit From bf863bccb662ff71a381f7c6d00e901d3c1c32fd Mon Sep 17 00:00:00 2001 From: Andrew Kroeger Date: Tue, 26 May 2009 15:22:13 -0500 Subject: s4:ldb:modules: Correct typos. --- source4/lib/ldb/common/ldb_controls.c | 4 +--- source4/lib/ldb/modules/asq.c | 2 +- source4/lib/ldb/modules/paged_results.c | 2 +- source4/lib/ldb/modules/sort.c | 2 +- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/source4/lib/ldb/common/ldb_controls.c b/source4/lib/ldb/common/ldb_controls.c index 0c587e0905..6f127d8c39 100644 --- a/source4/lib/ldb/common/ldb_controls.c +++ b/source4/lib/ldb/common/ldb_controls.c @@ -39,7 +39,6 @@ struct ldb_control *ldb_request_get_control(struct ldb_request *req, const char { int i; - /* check if there's a paged request control */ if (req->controls != NULL) { for (i = 0; req->controls[i]; i++) { if (strcmp(oid, req->controls[i]->oid) == 0) { @@ -59,7 +58,6 @@ struct ldb_control *ldb_reply_get_control(struct ldb_reply *rep, const char *oid { int i; - /* check if there's a paged request control */ if (rep->controls != NULL) { for (i = 0; rep->controls[i]; i++) { if (strcmp(oid, rep->controls[i]->oid) == 0) { @@ -75,7 +73,7 @@ struct ldb_control *ldb_reply_get_control(struct ldb_reply *rep, const char *oid /* saves the current controls list into the "saver" and replace the one in req with a new one excluding the "exclude" control */ -/* returns False on error */ +/* returns 0 on error */ int save_controls(struct ldb_control *exclude, struct ldb_request *req, struct ldb_control ***saver) { struct ldb_control **lcs; diff --git a/source4/lib/ldb/modules/asq.c b/source4/lib/ldb/modules/asq.c index 475b609e41..dd5afd868c 100644 --- a/source4/lib/ldb/modules/asq.c +++ b/source4/lib/ldb/modules/asq.c @@ -351,7 +351,7 @@ static int asq_search(struct ldb_module *module, struct ldb_request *req) ldb = ldb_module_get_ctx(module); - /* check if there's a paged request control */ + /* check if there's an ASQ control */ control = ldb_request_get_control(req, LDB_CONTROL_ASQ_OID); if (control == NULL) { /* not found go on */ diff --git a/source4/lib/ldb/modules/paged_results.c b/source4/lib/ldb/modules/paged_results.c index 2a06c5e6c5..f2692305d5 100644 --- a/source4/lib/ldb/modules/paged_results.c +++ b/source4/lib/ldb/modules/paged_results.c @@ -408,7 +408,7 @@ static int paged_request_init(struct ldb_module *module) ret = ldb_mod_register_control(module, LDB_CONTROL_PAGED_RESULTS_OID); if (ret != LDB_SUCCESS) { ldb_debug(ldb, LDB_DEBUG_WARNING, - "paged_request:" + "paged_results:" "Unable to register control with rootdse!\n"); } diff --git a/source4/lib/ldb/modules/sort.c b/source4/lib/ldb/modules/sort.c index 309101c32b..b4f76e1007 100644 --- a/source4/lib/ldb/modules/sort.c +++ b/source4/lib/ldb/modules/sort.c @@ -255,7 +255,7 @@ static int server_sort_search(struct ldb_module *module, struct ldb_request *req ldb = ldb_module_get_ctx(module); - /* check if there's a paged request control */ + /* check if there's a server sort control */ control = ldb_request_get_control(req, LDB_CONTROL_SERVER_SORT_OID); if (control == NULL) { /* not found go on */ -- cgit From 73af16c0e7e599ca7f93b9769a42ae4ce0ce7a3e Mon Sep 17 00:00:00 2001 From: Andrew Kroeger Date: Sun, 24 May 2009 17:40:57 -0500 Subject: s4:ldb_modules: Correct typos. --- source4/dsdb/samdb/ldb_modules/kludge_acl.c | 2 +- source4/dsdb/samdb/ldb_modules/show_deleted.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source4/dsdb/samdb/ldb_modules/kludge_acl.c b/source4/dsdb/samdb/ldb_modules/kludge_acl.c index 0b5994bb88..5bed28b00c 100644 --- a/source4/dsdb/samdb/ldb_modules/kludge_acl.c +++ b/source4/dsdb/samdb/ldb_modules/kludge_acl.c @@ -514,7 +514,7 @@ static int kludge_acl_init(struct ldb_module *module) ret = ldb_mod_register_control(module, LDB_CONTROL_SD_FLAGS_OID); if (ret != LDB_SUCCESS) { ldb_debug(ldb, LDB_DEBUG_ERROR, - "partition: Unable to register control with rootdse!\n"); + "kludge_acl: Unable to register control with rootdse!\n"); return LDB_ERR_OPERATIONS_ERROR; } diff --git a/source4/dsdb/samdb/ldb_modules/show_deleted.c b/source4/dsdb/samdb/ldb_modules/show_deleted.c index d619558c21..b4f52d7cde 100644 --- a/source4/dsdb/samdb/ldb_modules/show_deleted.c +++ b/source4/dsdb/samdb/ldb_modules/show_deleted.c @@ -145,7 +145,7 @@ static int show_deleted_init(struct ldb_module *module) ret = ldb_mod_register_control(module, LDB_CONTROL_SHOW_DELETED_OID); if (ret != LDB_SUCCESS) { ldb_debug(ldb, LDB_DEBUG_ERROR, - "extended_dn: Unable to register control with rootdse!\n"); + "show_deleted: Unable to register control with rootdse!\n"); return LDB_ERR_OPERATIONS_ERROR; } -- cgit From 93e16a08d46587a6eacaa05cd462ea316e9da8e4 Mon Sep 17 00:00:00 2001 From: Björn Jacke Date: Tue, 26 May 2009 22:37:17 +0200 Subject: s3: fix build on systems with struct stat member st_flags --- source3/include/includes.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source3/include/includes.h b/source3/include/includes.h index a2f6048c27..ba3866a03a 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -450,6 +450,9 @@ struct stat_ex { struct timespec st_ex_btime; /* birthtime */ blksize_t st_ex_blksize; blkcnt_t st_ex_blocks; +#ifdef HAVE_STAT_ST_FLAGS + uint32_t st_ex_flags; +#endif /* * Add space for VFS internal extensions. The initial user of this -- cgit From 4db54fff13c2dfd1ea307faa32cf1dd34916c924 Mon Sep 17 00:00:00 2001 From: Björn Jacke Date: Tue, 26 May 2009 23:19:00 +0200 Subject: Revert "s3: fix build on systems with struct stat member st_flags" for a cleaner and more complete patch that Volker has in the queue :-) --- source3/include/includes.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/source3/include/includes.h b/source3/include/includes.h index ba3866a03a..a2f6048c27 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -450,9 +450,6 @@ struct stat_ex { struct timespec st_ex_btime; /* birthtime */ blksize_t st_ex_blksize; blkcnt_t st_ex_blocks; -#ifdef HAVE_STAT_ST_FLAGS - uint32_t st_ex_flags; -#endif /* * Add space for VFS internal extensions. The initial user of this -- cgit From dd0506d15ddb01b8f6e7b6be604a3445b73db434 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 26 May 2009 22:39:50 +0200 Subject: Attempt to fix the build on NetBSD --- source3/include/includes.h | 3 +++ source3/lib/system.c | 6 ++++++ source3/smbd/trans2.c | 6 ------ 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/source3/include/includes.h b/source3/include/includes.h index a2f6048c27..0d66c1cd6b 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -451,6 +451,9 @@ struct stat_ex { blksize_t st_ex_blksize; blkcnt_t st_ex_blocks; + uint32_t st_ex_flags; + uint32_t st_ex_mask; + /* * Add space for VFS internal extensions. The initial user of this * would be the onefs modules, passing the snapid from the stat calls diff --git a/source3/lib/system.c b/source3/lib/system.c index 5158750f98..d9d3266fbc 100644 --- a/source3/lib/system.c +++ b/source3/lib/system.c @@ -477,6 +477,12 @@ static void init_stat_ex_from_stat (struct stat_ex *dst, dst->st_ex_btime = get_create_timespec(src); dst->st_ex_blksize = src->st_blksize; dst->st_ex_blocks = src->st_blocks; + +#ifdef HAVE_STAT_ST_FLAGS + dst->st_ex_flags = src->st_flags; +#else + dst->st_ex_flags = 0; +#endif } /******************************************************************* diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index ef7f617010..1d95c207ba 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -3613,7 +3613,6 @@ static const struct {unsigned stat_fflag; unsigned smb_fflag;} static void map_info2_flags_from_sbuf(const SMB_STRUCT_STAT *psbuf, uint32 *smb_fflags, uint32 *smb_fmask) { -#ifdef HAVE_STAT_ST_FLAGS int i; for (i = 0; i < ARRAY_SIZE(info2_flags_map); ++i) { @@ -3622,7 +3621,6 @@ static void map_info2_flags_from_sbuf(const SMB_STRUCT_STAT *psbuf, *smb_fflags |= info2_flags_map[i].smb_fflag; } } -#endif /* HAVE_STAT_ST_FLAGS */ } static bool map_info2_flags_to_sbuf(const SMB_STRUCT_STAT *psbuf, @@ -3630,7 +3628,6 @@ static bool map_info2_flags_to_sbuf(const SMB_STRUCT_STAT *psbuf, const uint32 smb_fmask, int *stat_fflags) { -#ifdef HAVE_STAT_ST_FLAGS uint32 max_fmask = 0; int i; @@ -3660,9 +3657,6 @@ static bool map_info2_flags_to_sbuf(const SMB_STRUCT_STAT *psbuf, } return True; -#else - return False; -#endif /* HAVE_STAT_ST_FLAGS */ } -- cgit From 3ada1a19ab1309b0435ee84844b433b06ead0196 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 26 May 2009 23:37:14 +0200 Subject: Attempt to fix the build on HP/UX --- source3/configure.in | 2 ++ source3/include/includes.h | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/source3/configure.in b/source3/configure.in index 44374b989c..f980911666 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -2778,6 +2778,8 @@ if test x"$samba_cv_HAVE_STAT_ST_BLOCKS" = x"yes"; then AC_DEFINE(HAVE_STAT_ST_BLOCKS,1,[Whether the stat struct has a st_block property]) fi +AC_CHECK_TYPES([blksize_t, blkcnt_t], [], [], [[#include ]]) + AC_CACHE_CHECK([for st_blksize in struct stat],samba_cv_HAVE_STAT_ST_BLKSIZE,[ AC_TRY_COMPILE([#include #include diff --git a/source3/include/includes.h b/source3/include/includes.h index 0d66c1cd6b..7bb72be692 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -431,6 +431,16 @@ typedef uint64_t br_off; #define IVAL_TO_SMB_OFF_T(buf,off) ((SMB_OFF_T)(( ((uint32)(IVAL((buf),(off)))) & 0xFFFFFFFF ))) #endif +#ifndef HAVE_BLKSIZE_T +/* This is mainly for HP/UX which defines st_blksize as long */ +typedef blksize_t long; +#endif + +#ifndef HAVE_BLKCNT_T +/* This is mainly for HP/UX which doesn't have blkcnt_t */ +typedef blkcnt_t long; +#endif + /* * Type for stat structure. */ -- cgit From b21656f09a1127f10de75b9cc098e07cf3135d3c Mon Sep 17 00:00:00 2001 From: Andrew Kroeger Date: Sun, 24 May 2009 01:48:49 -0500 Subject: s4:tevent: Increase trace debug level to 50. The sheer volume of messages generated by tevent when the trace level is set to 10 makes it difficult to debug issues in a level 10 log. Increasing this to 50 allows tevent tracing to be enabled if needed, but otherwise keeps the extra chatter out of a level 10 log. --- source4/lib/events/tevent_s4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/lib/events/tevent_s4.c b/source4/lib/events/tevent_s4.c index 06bfbf61ed..1898269c2c 100644 --- a/source4/lib/events/tevent_s4.c +++ b/source4/lib/events/tevent_s4.c @@ -42,7 +42,7 @@ static void ev_wrap_debug(void *context, enum tevent_debug_level level, samba_level = 2; break; case TEVENT_DEBUG_TRACE: - samba_level = 10; + samba_level = 50; break; }; -- cgit From 8c871706e0c6cf42e06f33b7bfeed7fb5a7d4ff0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 26 May 2009 14:43:49 +1000 Subject: Add DOMAIN_RID_KRBTGT define to security.idl --- librpc/gen_ndr/security.h | 1 + librpc/idl/security.idl | 1 + 2 files changed, 2 insertions(+) diff --git a/librpc/gen_ndr/security.h b/librpc/gen_ndr/security.h index f90dd413a8..16635f0bb8 100644 --- a/librpc/gen_ndr/security.h +++ b/librpc/gen_ndr/security.h @@ -126,6 +126,7 @@ #define DOMAIN_RID_GUEST ( 501 ) #define DOMAIN_RID_ADMINS ( 512 ) #define DOMAIN_RID_USERS ( 513 ) +#define DOMAIN_RID_KRBTGT ( 514 ) #define DOMAIN_RID_DOMAIN_MEMBERS ( 515 ) #define DOMAIN_RID_DCS ( 516 ) #define DOMAIN_RID_CERT_ADMINS ( 517 ) diff --git a/librpc/idl/security.idl b/librpc/idl/security.idl index 825ce96d71..9e47ff45fc 100644 --- a/librpc/idl/security.idl +++ b/librpc/idl/security.idl @@ -226,6 +226,7 @@ interface security const int DOMAIN_RID_GUEST = 501; const int DOMAIN_RID_ADMINS = 512; const int DOMAIN_RID_USERS = 513; + const int DOMAIN_RID_KRBTGT = 514; const int DOMAIN_RID_DOMAIN_MEMBERS = 515; const int DOMAIN_RID_DCS = 516; const int DOMAIN_RID_CERT_ADMINS = 517; -- cgit From 5264ad627d59e0f2cb03cb3bdd3baf8943d7fa5b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 26 May 2009 13:09:57 +1000 Subject: Handle the krbtgt special case by looking for RID -514 It turns out (seen in MS-SAMR 3.1.1.7.1 for example) that the primary way the krbtgt account is recognised as special is that RID. This should fix issues such as 'password expired' on the kpasswd service. Andrew Bartlett --- source4/kdc/hdb-samba4.c | 78 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 26 deletions(-) diff --git a/source4/kdc/hdb-samba4.c b/source4/kdc/hdb-samba4.c index 1fdb744a84..585285795f 100644 --- a/source4/kdc/hdb-samba4.c +++ b/source4/kdc/hdb-samba4.c @@ -38,6 +38,7 @@ #include "lib/ldb/include/ldb.h" #include "lib/ldb/include/ldb_errors.h" #include "librpc/gen_ndr/netlogon.h" +#include "libcli/security/security.h" #include "auth/auth.h" #include "auth/credentials/credentials.h" #include "auth/auth_sam.h" @@ -499,7 +500,9 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db, struct hdb_ldb_private *p; NTTIME acct_expiry; + NTSTATUS status; + uint32_t rid; struct ldb_message_element *objectclasses; struct ldb_val computer_val; const char *samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL); @@ -580,49 +583,70 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db, /* First try and figure out the flags based on the userAccountControl */ entry_ex->entry.flags = uf2HDBFlags(context, userAccountControl, ent_type); - if (ent_type == HDB_SAMBA4_ENT_TYPE_KRBTGT) { - entry_ex->entry.flags.invalid = 0; - entry_ex->entry.flags.server = 1; - entry_ex->entry.flags.forwardable = 1; - entry_ex->entry.flags.ok_as_delegate = 1; - } - /* Windows 2008 seems to enforce this (very sensible) rule by * default - don't allow offline attacks on a user's password * by asking for a ticket to them as a service (encrypted with * their probably patheticly insecure password) */ - if (lp_parm_bool(lp_ctx, NULL, "kdc", "require spn for service", true)) { + if (entry_ex->entry.flags.server + && lp_parm_bool(lp_ctx, NULL, "kdc", "require spn for service", true)) { if (!is_computer && !ldb_msg_find_attr_as_string(msg, "servicePrincipalName", NULL)) { entry_ex->entry.flags.server = 0; } } - /* use 'whenCreated' */ - entry_ex->entry.created_by.time = ldb_msg_find_krb5time_ldap_time(msg, "whenCreated", 0); - /* use '???' */ - entry_ex->entry.created_by.principal = NULL; + { + /* These (created_by, modified_by) parts of the entry are not relevant for Samba4's use + * of the Heimdal KDC. They are stored in a the traditional + * DB for audit purposes, and still form part of the structure + * we must return */ + + /* use 'whenCreated' */ + entry_ex->entry.created_by.time = ldb_msg_find_krb5time_ldap_time(msg, "whenCreated", 0); + /* use '???' */ + entry_ex->entry.created_by.principal = NULL; + + entry_ex->entry.modified_by = (Event *) malloc(sizeof(Event)); + if (entry_ex->entry.modified_by == NULL) { + krb5_set_error_string(context, "malloc: out of memory"); + ret = ENOMEM; + goto out; + } + + /* use 'whenChanged' */ + entry_ex->entry.modified_by->time = ldb_msg_find_krb5time_ldap_time(msg, "whenChanged", 0); + /* use '???' */ + entry_ex->entry.modified_by->principal = NULL; + } - entry_ex->entry.modified_by = (Event *) malloc(sizeof(Event)); - if (entry_ex->entry.modified_by == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); - ret = ENOMEM; + + /* The lack of password controls etc applies to krbtgt by + * virtue of being that particular RID */ + status = dom_sid_split_rid(NULL, samdb_result_dom_sid(mem_ctx, msg, "objectSid"), NULL, &rid); + + if (!NT_STATUS_IS_OK(status)) { + ret = EINVAL; goto out; } - /* use 'whenChanged' */ - entry_ex->entry.modified_by->time = ldb_msg_find_krb5time_ldap_time(msg, "whenChanged", 0); - /* use '???' */ - entry_ex->entry.modified_by->principal = NULL; + if (rid == DOMAIN_RID_KRBTGT) { + entry_ex->entry.valid_end = NULL; + entry_ex->entry.pw_end = NULL; - entry_ex->entry.valid_start = NULL; + entry_ex->entry.flags.invalid = 0; + entry_ex->entry.flags.server = 1; + entry_ex->entry.flags.change_pw = 1; + entry_ex->entry.flags.client = 0; + entry_ex->entry.flags.forwardable = 1; + entry_ex->entry.flags.ok_as_delegate = 1; + } else if (entry_ex->entry.flags.server && ent_type == HDB_SAMBA4_ENT_TYPE_SERVER) { + /* The account/password expiry only applies when the account is used as a + * client (ie password login), not when used as a server */ - /* The account/password expiry only applies when the account is used as a - * client (ie password login), not when used as a server */ - if (ent_type == HDB_SAMBA4_ENT_TYPE_KRBTGT || ent_type == HDB_SAMBA4_ENT_TYPE_SERVER) { /* Make very well sure we don't use this for a client, - * it could bypass the above password restrictions */ + * it could bypass the password restrictions */ entry_ex->entry.flags.client = 0; + entry_ex->entry.valid_end = NULL; entry_ex->entry.pw_end = NULL; @@ -653,7 +677,9 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db, *entry_ex->entry.valid_end = nt_time_to_unix(acct_expiry); } } - + + entry_ex->entry.valid_start = NULL; + entry_ex->entry.max_life = NULL; entry_ex->entry.max_renew = NULL; -- cgit From 6d91ac2a646ae47d359914503030cab51b2c9d16 Mon Sep 17 00:00:00 2001 From: Steven Danneman Date: Fri, 22 May 2009 16:57:52 -0700 Subject: s3/docs Add manpage for "map untrusted to domain" parameter This fixes bug 6352. --- .../smbdotconf/security/mapuntrustedtodomain.xml | 33 ++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 docs-xml/smbdotconf/security/mapuntrustedtodomain.xml diff --git a/docs-xml/smbdotconf/security/mapuntrustedtodomain.xml b/docs-xml/smbdotconf/security/mapuntrustedtodomain.xml new file mode 100644 index 0000000000..bcf65e6eb6 --- /dev/null +++ b/docs-xml/smbdotconf/security/mapuntrustedtodomain.xml @@ -0,0 +1,33 @@ + + + + If a client connects to smbd using an untrusted domain name, such as + BOGUS\user, smbd replaces the BOGUS domain with it's SAM name before + attempting to authenticate that user. In the case where smbd is acting as + a PDC this will be DOMAIN\user. In the case where smbd is acting as a + domain member server or a standalone server this will be WORKSTATION\user. + + + + In previous versions of Samba (pre 3.4), if smbd was acting as a domain + member server, the BOGUS domain name would instead be replaced by the + primary domain which smbd was a member of. In this case authentication + would be deferred off to a DC using the credentials DOMAIN\user. + + + + When this parameter is set to yes smbd provides the + legacy behavior of mapping untrusted domain names to the primary domain. + When smbd is not acting as a domain member server, this parameter has no + effect. + + + + +no + -- cgit From 078343906d9e403d250639235bf634e1a71e682f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 18 May 2009 15:56:31 +1000 Subject: Detect missing 'witch' before detecting missing autoconf --- source4/autogen.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source4/autogen.sh b/source4/autogen.sh index 8b97023073..2d995caeae 100755 --- a/source4/autogen.sh +++ b/source4/autogen.sh @@ -22,7 +22,12 @@ TESTAUTOCONF="autoconf autoconf-2.53 autoconf2.50 autoconf259 autoconf253" AUTOHEADERFOUND="0" AUTOCONFFOUND="0" - +if which which > /dev/null 2>&1; then + echo -n +else + echo "$0: need 'which' to figure out if we have the right autoconf to build samba from git" >&2 + exit 1 +fi ## ## Look for autoheader ## -- cgit From ab5b1431a028482e4ab65a584db6aa35979680b2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 27 May 2009 08:09:23 +0200 Subject: Gna, how long do I program in C now??? :-) --- source3/include/includes.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/include/includes.h b/source3/include/includes.h index 7bb72be692..e468bd5c38 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -433,12 +433,12 @@ typedef uint64_t br_off; #ifndef HAVE_BLKSIZE_T /* This is mainly for HP/UX which defines st_blksize as long */ -typedef blksize_t long; +typedef long blksize_t; #endif #ifndef HAVE_BLKCNT_T /* This is mainly for HP/UX which doesn't have blkcnt_t */ -typedef blkcnt_t long; +typedef long blkcnt_t; #endif /* -- cgit From d5e3d9478dcb2feed44287f67eeab39e49eed2ac Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 24 May 2009 21:46:53 +0200 Subject: Fix some nonempty blank lines --- source3/smbd/dosmode.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 9a3470312f..6468544748 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -3,17 +3,17 @@ dos mode handling functions Copyright (C) Andrew Tridgell 1992-1998 Copyright (C) James Peach 2006 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -117,7 +117,7 @@ mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname, if (lp_map_system(SNUM(conn)) && IS_DOS_SYSTEM(dosmode)) result |= S_IXGRP; - + if (lp_map_hidden(SNUM(conn)) && IS_DOS_HIDDEN(dosmode)) result |= S_IXOTH; @@ -162,10 +162,10 @@ static uint32 dos_mode_from_sbuf(connection_struct *conn, const char *path, SMB_ if (MAP_SYSTEM(conn) && ((sbuf->st_ex_mode & S_IXGRP) != 0)) result |= aSYSTEM; - + if (MAP_HIDDEN(conn) && ((sbuf->st_ex_mode & S_IXOTH) != 0)) result |= aHIDDEN; - + if (S_ISDIR(sbuf->st_ex_mode)) result = aDIR | (result & aRONLY); @@ -179,7 +179,7 @@ static uint32 dos_mode_from_sbuf(connection_struct *conn, const char *path, SMB_ if (result & aSYSTEM) DEBUG(8, ("s")); if (result & aDIR ) DEBUG(8, ("d")); if (result & aARCH ) DEBUG(8, ("a")); - + DEBUG(8,("\n")); return result; } @@ -237,7 +237,7 @@ static bool get_ea_dos_attribute(connection_struct *conn, const char *path,SMB_S if (dosattr & aSYSTEM) DEBUG(8, ("s")); if (dosattr & aDIR ) DEBUG(8, ("d")); if (dosattr & aARCH ) DEBUG(8, ("a")); - + DEBUG(8,("\n")); return True; @@ -332,7 +332,7 @@ uint32 dos_mode_msdfs(connection_struct *conn, const char *path,SMB_STRUCT_STAT result |= aHIDDEN; } } - + result |= dos_mode_from_sbuf(conn, path, sbuf); /* Optimization : Only call is_hidden_path if it's not already @@ -349,7 +349,7 @@ uint32 dos_mode_msdfs(connection_struct *conn, const char *path,SMB_STRUCT_STAT if (result & aDIR ) DEBUG(8, ("d")); if (result & aARCH ) DEBUG(8, ("a")); if (result & FILE_ATTRIBUTE_SPARSE ) DEBUG(8, ("[sparse]")); - + DEBUG(8,("\n")); return(result); @@ -493,7 +493,7 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf) result |= aHIDDEN; } } - + #ifdef HAVE_STAT_DOS_FLAGS used_stat_dos_flags = get_stat_dos_flags(conn, path, sbuf, &result); #endif @@ -506,7 +506,6 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf) } } - offline = SMB_VFS_IS_OFFLINE(conn, path, sbuf); if (S_ISREG(sbuf->st_ex_mode) && offline) { result |= FILE_ATTRIBUTE_OFFLINE; @@ -526,7 +525,7 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf) if (result & aDIR ) DEBUG(8, ("d")); if (result & aARCH ) DEBUG(8, ("a")); if (result & FILE_ATTRIBUTE_SPARSE ) DEBUG(8, ("[sparse]")); - + DEBUG(8,("\n")); return(result); @@ -573,7 +572,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname, dosmode &= ~aDIR; old_mode = dos_mode(conn,fname,st); - + if (dosmode & FILE_ATTRIBUTE_OFFLINE) { if (!(old_mode & FILE_ATTRIBUTE_OFFLINE)) { lret = SMB_VFS_SET_OFFLINE(conn, fname); -- cgit From a8ffc286a4fd3fffcc934462b9f6f5593f910661 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 24 May 2009 22:16:34 +0200 Subject: Fix a size_t/int warning --- source3/modules/nfs4_acls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c index 04ea73f45e..0941eb94f5 100644 --- a/source3/modules/nfs4_acls.c +++ b/source3/modules/nfs4_acls.c @@ -316,7 +316,7 @@ static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf, } DEBUG(10, ("smb_get_nt_acl_nfs4_common successfully exited with sd_size %d\n", - ndr_size_security_descriptor(*ppdesc, NULL, 0))); + (int)ndr_size_security_descriptor(*ppdesc, NULL, 0))); return NT_STATUS_OK; } -- cgit From 4df33ec4a79c171097ea7ba7542e093ef5034863 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 24 May 2009 22:17:58 +0200 Subject: Fix the build of nfs4_acls.c --- source3/modules/nfs4_acls.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c index 0941eb94f5..10a3733c14 100644 --- a/source3/modules/nfs4_acls.c +++ b/source3/modules/nfs4_acls.c @@ -760,7 +760,8 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp, return NT_STATUS_OK; } - theacl = smbacl4_win2nfs4(fsp->fsp_name, psd->dacl, ¶ms, sbuf.st_uid, sbuf.st_gid); + theacl = smbacl4_win2nfs4(fsp->fsp_name, psd->dacl, ¶ms, + sbuf.st_ex_uid, sbuf.st_ex_gid); if (!theacl) return map_nt_error_from_unix(errno); -- cgit From 9a06f5e1713d54f0b179e2f6c5d050ef489cd373 Mon Sep 17 00:00:00 2001 From: Björn Jacke Date: Mon, 25 May 2009 14:55:04 +0200 Subject: s3: make passdb backend defaults to tdbsam --- source3/param/loadparm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 4bd7cb0f9d..57fdb6e044 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -4999,7 +4999,7 @@ static void init_globals(bool first_time_only) a large number of sites (tridge) */ Globals.bHostnameLookups = False; - string_set(&Globals.szPassdbBackend, "smbpasswd"); + string_set(&Globals.szPassdbBackend, "tdbsam"); string_set(&Globals.szLdapSuffix, ""); string_set(&Globals.szLdapMachineSuffix, ""); string_set(&Globals.szLdapUserSuffix, ""); -- cgit From 0d040ff448a67048c5bdade0c38ed0a923202c6e Mon Sep 17 00:00:00 2001 From: Björn Jacke Date: Wed, 27 May 2009 12:01:21 +0200 Subject: s3: update manpage as to the new passdb backend default --- docs-xml/smbdotconf/security/passdbbackend.xml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs-xml/smbdotconf/security/passdbbackend.xml b/docs-xml/smbdotconf/security/passdbbackend.xml index 487d8b8a9d..b761f970c0 100644 --- a/docs-xml/smbdotconf/security/passdbbackend.xml +++ b/docs-xml/smbdotconf/security/passdbbackend.xml @@ -16,8 +16,10 @@ Available backends can include: - smbpasswd - The default smbpasswd - backend. Takes a path to the smbpasswd file as an optional argument. + smbpasswd - The old plaintext passdb + backend. Some Samba features will not work if this passdb + backend is used. Takes a path to the smbpasswd file as an + optional argument. @@ -60,5 +62,5 @@ passdb backend = ldapsam:"ldap://ldap-1.example.com ldap-2.example.com" -smbpasswd +tdbsam -- cgit From ee4c1ed010d62e0522f6a96f40f1ebd2df89a6b6 Mon Sep 17 00:00:00 2001 From: Nadezhda Ivanova Date: Wed, 27 May 2009 13:49:51 +0300 Subject: Modified SamDB to accept options like Ldb. --- source4/scripting/python/samba/samdb.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py index 17b5450a3e..454a9d144c 100644 --- a/source4/scripting/python/samba/samdb.py +++ b/source4/scripting/python/samba/samdb.py @@ -36,14 +36,14 @@ class SamDB(samba.Ldb): """The SAM database.""" def __init__(self, url=None, session_info=None, credentials=None, - modules_dir=None, lp=None): + modules_dir=None, lp=None, options=None): """Open the Sam Database. :param url: URL of the database. """ self.lp = lp super(SamDB, self).__init__(session_info=session_info, credentials=credentials, - modules_dir=modules_dir, lp=lp) + modules_dir=modules_dir, lp=lp, options=options) glue.dsdb_set_global_schema(self) if url: self.connect(url) -- cgit From 84998cb85e59a92178d916f4e485c08fb826b838 Mon Sep 17 00:00:00 2001 From: Karolin Seeger Date: Wed, 27 May 2009 15:52:23 +0200 Subject: s3/docs: Fix build. $(DBLATEX) was empty. Please check! Karolin --- docs-xml/configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-xml/configure.ac b/docs-xml/configure.ac index 16a9aaad2a..cb2a3dfa3f 100644 --- a/docs-xml/configure.ac +++ b/docs-xml/configure.ac @@ -21,7 +21,7 @@ DOCS_TARGET_REQUIRE_PROGRAM(INKSCAPE, inkscape, PLUCKER) DOCS_TARGET_REQUIRE_PROGRAM(PNGTOPNM, pngtopnm, PS) DOCS_TARGET_REQUIRE_PROGRAM(PNMTOPS, pnmtops, PS) -DOCS_TARGET_REQUIRE_PROGRAM(DBLATEX, dblatex, LATEX) +DOCS_TARGET_REQUIRE_PROGRAM(DBLATEX, dblatex, DBLATEX) DOCS_TARGET_REQUIRE_PROGRAM(PLUCKERBUILD, plucker-build, PLUCKER) DOCS_TARGET_REQUIRE_PROGRAM(HTML2TEXT, html2text, TXT) DOCS_TARGET_REQUIRE_PROGRAM(PERL, perl, UNDOCUMENTED) -- cgit From 3046d307035f5fc4dff2940309170db5b444050b Mon Sep 17 00:00:00 2001 From: Karolin Seeger Date: Wed, 27 May 2009 16:04:11 +0200 Subject: Revert "s3/docs: Fix build." This reverts commit 84998cb85e59a92178d916f4e485c08fb826b838. Actually, the "fix" breaks the build. Works after 'make clean'. Sorry! --- docs-xml/configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-xml/configure.ac b/docs-xml/configure.ac index cb2a3dfa3f..16a9aaad2a 100644 --- a/docs-xml/configure.ac +++ b/docs-xml/configure.ac @@ -21,7 +21,7 @@ DOCS_TARGET_REQUIRE_PROGRAM(INKSCAPE, inkscape, PLUCKER) DOCS_TARGET_REQUIRE_PROGRAM(PNGTOPNM, pngtopnm, PS) DOCS_TARGET_REQUIRE_PROGRAM(PNMTOPS, pnmtops, PS) -DOCS_TARGET_REQUIRE_PROGRAM(DBLATEX, dblatex, DBLATEX) +DOCS_TARGET_REQUIRE_PROGRAM(DBLATEX, dblatex, LATEX) DOCS_TARGET_REQUIRE_PROGRAM(PLUCKERBUILD, plucker-build, PLUCKER) DOCS_TARGET_REQUIRE_PROGRAM(HTML2TEXT, html2text, TXT) DOCS_TARGET_REQUIRE_PROGRAM(PERL, perl, UNDOCUMENTED) -- cgit From 559e2eccdf98473ed244dcd2a0d1e43b02b2778e Mon Sep 17 00:00:00 2001 From: Karolin Seeger Date: Wed, 27 May 2009 18:14:17 +0200 Subject: s3/docs: Correct version number. Karolin --- docs-xml/Samba3-HOWTO/index.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-xml/Samba3-HOWTO/index.xml b/docs-xml/Samba3-HOWTO/index.xml index 87b07951c7..8321714867 100644 --- a/docs-xml/Samba3-HOWTO/index.xml +++ b/docs-xml/Samba3-HOWTO/index.xml @@ -3,7 +3,7 @@ -The Official Samba 3.2.x HOWTO and Reference Guide +The Official Samba 3.5.x HOWTO and Reference Guide -- cgit From 3d3f39838261ddc401053dadcc5bd8e6317a3a8e Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 27 May 2009 19:12:28 +0200 Subject: s3:idmap_tdb: filter out of range mappings in default idmap config This fixes bug #6415 Michael --- source3/winbindd/idmap_tdb.c | 73 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 57 insertions(+), 16 deletions(-) diff --git a/source3/winbindd/idmap_tdb.c b/source3/winbindd/idmap_tdb.c index 22c17578e6..90327434f0 100644 --- a/source3/winbindd/idmap_tdb.c +++ b/source3/winbindd/idmap_tdb.c @@ -593,8 +593,6 @@ static NTSTATUS idmap_tdb_db_init(struct idmap_domain *dom, const char *params) { NTSTATUS ret; struct idmap_tdb_context *ctx; - char *config_option = NULL; - const char *range; ctx = talloc(dom, struct idmap_tdb_context); if ( ! ctx) { @@ -602,29 +600,72 @@ static NTSTATUS idmap_tdb_db_init(struct idmap_domain *dom, const char *params) return NT_STATUS_NO_MEMORY; } - config_option = talloc_asprintf(ctx, "idmap config %s", dom->name); - if ( ! config_option) { - DEBUG(0, ("Out of memory!\n")); - ret = NT_STATUS_NO_MEMORY; - goto failed; - } + if (strequal(dom->name, "*")) { + uid_t low_uid = 0; + uid_t high_uid = 0; + gid_t low_gid = 0; + gid_t high_gid = 0; - ret = idmap_tdb_open_db(ctx, false, &ctx->db); - if ( ! NT_STATUS_IS_OK(ret)) { - goto failed; + ctx->filter_low_id = 0; + ctx->filter_high_id = 0; + + if (lp_idmap_uid(&low_uid, &high_uid)) { + ctx->filter_low_id = low_uid; + ctx->filter_high_id = high_uid; + } else { + DEBUG(3, ("Warning: 'idmap uid' not set!\n")); + } + + if (lp_idmap_gid(&low_gid, &high_gid)) { + if ((low_gid != low_uid) || (high_gid != high_uid)) { + DEBUG(1, ("Warning: 'idmap uid' and 'idmap gid'" + " ranges do not agree -- building " + "intersection\n")); + ctx->filter_low_id = MAX(ctx->filter_low_id, + low_gid); + ctx->filter_high_id = MIN(ctx->filter_high_id, + high_gid); + } + } else { + DEBUG(3, ("Warning: 'idmap gid' not set!\n")); + } + } else { + char *config_option = NULL; + const char *range; + + config_option = talloc_asprintf(ctx, "idmap config %s", dom->name); + if ( ! config_option) { + DEBUG(0, ("Out of memory!\n")); + ret = NT_STATUS_NO_MEMORY; + goto failed; + } + + range = lp_parm_const_string(-1, config_option, "range", NULL); + if (( ! range) || + (sscanf(range, "%u - %u", &ctx->filter_low_id, &ctx->filter_high_id) != 2)) + { + ctx->filter_low_id = 0; + ctx->filter_high_id = 0; + } + + talloc_free(config_option); } - range = lp_parm_const_string(-1, config_option, "range", NULL); - if (( ! range) || - (sscanf(range, "%u - %u", &ctx->filter_low_id, &ctx->filter_high_id) != 2) || - (ctx->filter_low_id > ctx->filter_high_id)) { + if (ctx->filter_low_id > ctx->filter_high_id) { ctx->filter_low_id = 0; ctx->filter_high_id = 0; } + DEBUG(10, ("idmap_tdb_db_init: filter range %u-%u loaded for domain " + "'%s'\n", ctx->filter_low_id, ctx->filter_high_id, dom->name)); + + ret = idmap_tdb_open_db(ctx, false, &ctx->db); + if ( ! NT_STATUS_IS_OK(ret)) { + goto failed; + } + dom->private_data = ctx; - talloc_free(config_option); return NT_STATUS_OK; failed: -- cgit From ca697a9e312c68f5b11180d66939496590f01f1a Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 27 May 2009 19:14:10 +0200 Subject: s3:idmap_tdb: add an entry debug statment to idmap_tdb_db_init() Michael --- source3/winbindd/idmap_tdb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source3/winbindd/idmap_tdb.c b/source3/winbindd/idmap_tdb.c index 90327434f0..c42cd74cbe 100644 --- a/source3/winbindd/idmap_tdb.c +++ b/source3/winbindd/idmap_tdb.c @@ -594,6 +594,8 @@ static NTSTATUS idmap_tdb_db_init(struct idmap_domain *dom, const char *params) NTSTATUS ret; struct idmap_tdb_context *ctx; + DEBUG(10, ("idmap_tdb_db_init called for domain '%s'\n", dom->name)); + ctx = talloc(dom, struct idmap_tdb_context); if ( ! ctx) { DEBUG(0, ("Out of memory!\n")); -- cgit From e12670a1053edf57af137026bd3fdb9fc7dfb0b2 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 27 May 2009 19:24:03 +0200 Subject: s3:idmap_tdb2: filter out of range mappings in default idmap config This fixes bug #6416 Michael --- source3/winbindd/idmap_tdb2.c | 61 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 12 deletions(-) diff --git a/source3/winbindd/idmap_tdb2.c b/source3/winbindd/idmap_tdb2.c index b2723270eb..d34d289906 100644 --- a/source3/winbindd/idmap_tdb2.c +++ b/source3/winbindd/idmap_tdb2.c @@ -357,8 +357,6 @@ static NTSTATUS idmap_tdb2_db_init(struct idmap_domain *dom, { NTSTATUS ret; struct idmap_tdb2_context *ctx; - char *config_option = NULL; - const char *range; NTSTATUS status; status = idmap_tdb2_open_db(); @@ -370,24 +368,63 @@ static NTSTATUS idmap_tdb2_db_init(struct idmap_domain *dom, return NT_STATUS_NO_MEMORY; } - config_option = talloc_asprintf(ctx, "idmap config %s", dom->name); - if ( ! config_option) { - DEBUG(0, ("Out of memory!\n")); - ret = NT_STATUS_NO_MEMORY; - goto failed; + if (strequal(dom->name, "*")) { + uid_t low_uid = 0; + uid_t high_uid = 0; + gid_t low_gid = 0; + gid_t high_gid = 0; + + ctx->filter_low_id = 0; + ctx->filter_high_id = 0; + + if (lp_idmap_uid(&low_uid, &high_uid)) { + ctx->filter_low_id = low_uid; + ctx->filter_high_id = high_uid; + } else { + DEBUG(3, ("Warning: 'idmap uid' not set!\n")); + } + + if (lp_idmap_gid(&low_gid, &high_gid)) { + if ((low_gid != low_uid) || (high_gid != high_uid)) { + DEBUG(1, ("Warning: 'idmap uid' and 'idmap gid'" + " ranges do not agree -- building " + "intersection\n")); + ctx->filter_low_id = MAX(ctx->filter_low_id, + low_gid); + ctx->filter_high_id = MIN(ctx->filter_high_id, + high_gid); + } + } else { + DEBUG(3, ("Warning: 'idmap gid' not set!\n")); + } + } else { + char *config_option = NULL; + const char *range; + config_option = talloc_asprintf(ctx, "idmap config %s", dom->name); + if ( ! config_option) { + DEBUG(0, ("Out of memory!\n")); + ret = NT_STATUS_NO_MEMORY; + goto failed; + } + + range = lp_parm_const_string(-1, config_option, "range", NULL); + if (( ! range) || + (sscanf(range, "%u - %u", &ctx->filter_low_id, &ctx->filter_high_id) != 2)) + { + ctx->filter_low_id = 0; + ctx->filter_high_id = 0; + } + + talloc_free(config_option); } - range = lp_parm_const_string(-1, config_option, "range", NULL); - if (( ! range) || - (sscanf(range, "%u - %u", &ctx->filter_low_id, &ctx->filter_high_id) != 2) || - (ctx->filter_low_id > ctx->filter_high_id)) { + if (ctx->filter_low_id > ctx->filter_high_id) { ctx->filter_low_id = 0; ctx->filter_high_id = 0; } dom->private_data = ctx; - talloc_free(config_option); return NT_STATUS_OK; failed: -- cgit From 3fe9859342c28fe9da7011fb18a5fb5de8b29fa6 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 27 May 2009 19:26:32 +0200 Subject: s3:idmap: fix a comment typo Michael --- source3/winbindd/idmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index c097170d03..4aa229cd66 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -761,7 +761,7 @@ NTSTATUS idmap_backends_sid_to_unixid(const char *domain, struct id_map *id) struct idmap_domain *dom; struct id_map *maps[2]; - DEBUG(10, ("idmap_backend_sid_to_unixid: domain = '%s', sid = [%s]\n", + DEBUG(10, ("idmap_backends_sid_to_unixid: domain = '%s', sid = [%s]\n", domain?domain:"NULL", sid_string_dbg(id->sid))); maps[0] = id; -- cgit From 75de7c0e87cc5ecea1a7d7e9b0103a8cc2827895 Mon Sep 17 00:00:00 2001 From: Marc VanHeyningen Date: Tue, 5 May 2009 22:07:40 +0000 Subject: s3: zero an uninitialized array Invalid pointers were being dereferenced in lookup_sids causing occasional seg faults. Signed-off-by: Tim Prouty --- source3/passdb/lookup_sid.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c index b45000e77e..3a03cfe081 100644 --- a/source3/passdb/lookup_sid.c +++ b/source3/passdb/lookup_sid.c @@ -468,12 +468,15 @@ static bool lookup_rids(TALLOC_CTX *mem_ctx, const DOM_SID *domain_sid, sid_string_dbg(domain_sid))); if (num_rids) { - *names = TALLOC_ARRAY(mem_ctx, const char *, num_rids); + *names = TALLOC_ZERO_ARRAY(mem_ctx, const char *, num_rids); *types = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_rids); if ((*names == NULL) || (*types == NULL)) { return false; } + + for (i = 0; i < num_rids; i++) + (*types)[i] = SID_NAME_UNKNOWN; } else { *names = NULL; *types = NULL; -- cgit From a4887e250b84c321c75d54b9d3adf6fcf7c27fed Mon Sep 17 00:00:00 2001 From: Marc VanHeyningen Date: Tue, 5 May 2009 21:18:50 +0000 Subject: s3: Allow child processes to exit gracefully if we are out of fds When we run out of file descriptors for some reason, every new connection forks a child that immediately panics causing smbd to coredump. This seems unnecessarily harsh; with this code change we now catch that error and merely log a message about it and exit without the core dump. Signed-off-by: Tim Prouty --- source3/include/proto.h | 2 +- source3/lib/util.c | 12 ++++++------ source3/nmbd/asyncdns.c | 4 ++-- source3/nmbd/nmbd.c | 4 ++-- source3/printing/print_cups.c | 4 ++-- source3/printing/printing.c | 5 +++-- source3/smbd/server.c | 19 +++++++++++++------ source3/winbindd/winbindd.c | 5 +++-- source3/winbindd/winbindd_dual.c | 5 +++-- 9 files changed, 35 insertions(+), 25 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index c78d2c8e0b..717a972505 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1106,7 +1106,7 @@ char *clean_name(TALLOC_CTX *ctx, const char *s); ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos); int set_blocking(int fd, bool set); void smb_msleep(unsigned int t); -bool reinit_after_fork(struct messaging_context *msg_ctx, +NTSTATUS reinit_after_fork(struct messaging_context *msg_ctx, struct event_context *ev_ctx, bool parent_longlived); bool yesno(const char *p); diff --git a/source3/lib/util.c b/source3/lib/util.c index 13f7e3c9ee..8e67edeae6 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -927,11 +927,11 @@ void smb_msleep(unsigned int t) #endif } -bool reinit_after_fork(struct messaging_context *msg_ctx, +NTSTATUS reinit_after_fork(struct messaging_context *msg_ctx, struct event_context *ev_ctx, bool parent_longlived) { - NTSTATUS status; + NTSTATUS status = NT_STATUS_OK; /* Reset the state of the random * number generation system, so @@ -942,7 +942,8 @@ bool reinit_after_fork(struct messaging_context *msg_ctx, /* tdb needs special fork handling */ if (tdb_reopen_all(parent_longlived ? 1 : 0) == -1) { DEBUG(0,("tdb_reopen_all failed.\n")); - return false; + status = NT_STATUS_OPEN_FAILED; + goto done; } if (ev_ctx) { @@ -958,11 +959,10 @@ bool reinit_after_fork(struct messaging_context *msg_ctx, if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("messaging_reinit() failed: %s\n", nt_errstr(status))); - return false; } } - - return true; + done: + return status; } /**************************************************************************** diff --git a/source3/nmbd/asyncdns.c b/source3/nmbd/asyncdns.c index 0736a66fb8..85729ae7ac 100644 --- a/source3/nmbd/asyncdns.c +++ b/source3/nmbd/asyncdns.c @@ -164,8 +164,8 @@ void start_async_dns(void) CatchSignal(SIGHUP, SIG_IGN); CatchSignal(SIGTERM, SIGNAL_CAST sig_term ); - if (!reinit_after_fork(nmbd_messaging_context(), - nmbd_event_context(), true)) { + if (!NT_STATUS_IS_OK(reinit_after_fork(nmbd_messaging_context(), + nmbd_event_context(), true))) { DEBUG(0,("reinit_after_fork() failed\n")); smb_panic("reinit_after_fork() failed"); } diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c index daf4c295a6..903dc36d53 100644 --- a/source3/nmbd/nmbd.c +++ b/source3/nmbd/nmbd.c @@ -913,8 +913,8 @@ static bool open_sockets(bool isdaemon, int port) pidfile_create("nmbd"); - if (!reinit_after_fork(nmbd_messaging_context(), - nmbd_event_context(), false)) { + if (!NT_STATUS_IS_OK(reinit_after_fork(nmbd_messaging_context(), + nmbd_event_context(), false))) { DEBUG(0,("reinit_after_fork() failed\n")); exit(1); } diff --git a/source3/printing/print_cups.c b/source3/printing/print_cups.c index 7edfb5edbe..18f42138c9 100644 --- a/source3/printing/print_cups.c +++ b/source3/printing/print_cups.c @@ -433,8 +433,8 @@ static bool cups_pcap_load_async(int *pfd) close_all_print_db(); - if (!reinit_after_fork(smbd_messaging_context(), - smbd_event_context(), true)) { + if (!NT_STATUS_IS_OK(reinit_after_fork(smbd_messaging_context(), + smbd_event_context(), true))) { DEBUG(0,("cups_pcap_load_async: reinit_after_fork() failed\n")); smb_panic("cups_pcap_load_async: reinit_after_fork() failed"); } diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 3f337d01be..e73669fef5 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -1436,8 +1436,9 @@ void start_background_queue(void) close(pause_pipe[0]); pause_pipe[0] = -1; - if (!reinit_after_fork(smbd_messaging_context(), - smbd_event_context(), true)) { + if (!NT_STATUS_IS_OK(reinit_after_fork(smbd_messaging_context(), + smbd_event_context(), + true))) { DEBUG(0,("reinit_after_fork() failed\n")); smb_panic("reinit_after_fork() failed"); } diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 67836f785b..685b26fa1a 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -356,6 +356,7 @@ static void smbd_accept_connection(struct tevent_context *ev, pid = sys_fork(); if (pid == 0) { + NTSTATUS status = NT_STATUS_OK; /* Child code ... */ am_parent = 0; @@ -374,10 +375,15 @@ static void smbd_accept_connection(struct tevent_context *ev, talloc_free(s->parent); s = NULL; - if (!reinit_after_fork( - smbd_messaging_context(), - smbd_event_context(), - true)) { + status = reinit_after_fork(smbd_messaging_context(), + smbd_event_context(), true); + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status, + NT_STATUS_TOO_MANY_OPENED_FILES)) { + DEBUG(0,("child process cannot initialize " + "because too many files are open\n")); + goto exit; + } DEBUG(0,("reinit_after_fork() failed\n")); smb_panic("reinit_after_fork() failed"); } @@ -386,6 +392,7 @@ static void smbd_accept_connection(struct tevent_context *ev, smbd_setup_sig_hup_handler(); smbd_process(); + exit: exit_server_cleanly("end of child"); return; } else if (pid < 0) { @@ -1122,8 +1129,8 @@ extern void build_options(bool screen); if (is_daemon) pidfile_create("smbd"); - if (!reinit_after_fork(smbd_messaging_context(), - smbd_event_context(), false)) { + if (!NT_STATUS_IS_OK(reinit_after_fork(smbd_messaging_context(), + smbd_event_context(), false))) { DEBUG(0,("reinit_after_fork() failed\n")); exit(1); } diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index e1ce223475..2b25616cf7 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -1304,8 +1304,9 @@ int main(int argc, char **argv, char **envp) * winbindd-specific resources we must free yet. JRA. */ - if (!reinit_after_fork(winbind_messaging_context(), - winbind_event_context(), false)) { + if (!NT_STATUS_IS_OK(reinit_after_fork(winbind_messaging_context(), + winbind_event_context(), + false))) { DEBUG(0,("reinit_after_fork() failed\n")); exit(1); } diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c index a69d34f30c..6fb0b5857c 100644 --- a/source3/winbindd/winbindd_dual.c +++ b/source3/winbindd/winbindd_dual.c @@ -1121,8 +1121,9 @@ bool winbindd_reinit_after_fork(const char *logfilename) struct winbindd_domain *domain; struct winbindd_child *cl; - if (!reinit_after_fork(winbind_messaging_context(), - winbind_event_context(), true)) { + if (!NT_STATUS_IS_OK(reinit_after_fork(winbind_messaging_context(), + winbind_event_context(), + true))) { DEBUG(0,("reinit_after_fork() failed\n")); return false; } -- cgit From c299833bf8e6506c793d6e8283743949aaac9ef4 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Wed, 27 May 2009 12:52:37 -0700 Subject: tdb: Fix some recently introduced warnings in tdbtool --- lib/tdb/tools/tdbtool.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/tdb/tools/tdbtool.c b/lib/tdb/tools/tdbtool.c index 3220e47b13..c0814e11de 100644 --- a/lib/tdb/tools/tdbtool.c +++ b/lib/tdb/tools/tdbtool.c @@ -401,8 +401,8 @@ static void speed_tdb(const char *tlimit) do { long int r = random(); TDB_DATA key, dbuf; - key.dptr = "store test"; - key.dsize = strlen(key.dptr); + key.dptr = (unsigned char *)"store test"; + key.dsize = strlen((char *)key.dptr); dbuf.dptr = (unsigned char *)&r; dbuf.dsize = sizeof(r); tdb_store(tdb, key, dbuf, TDB_REPLACE); @@ -417,8 +417,8 @@ static void speed_tdb(const char *tlimit) do { long int r = random(); TDB_DATA key, dbuf; - key.dptr = "store test"; - key.dsize = strlen(key.dptr); + key.dptr = (unsigned char *)"store test"; + key.dsize = strlen((char *)key.dptr); dbuf.dptr = (unsigned char *)&r; dbuf.dsize = sizeof(r); tdb_fetch(tdb, key); @@ -433,8 +433,8 @@ static void speed_tdb(const char *tlimit) do { long int r = random(); TDB_DATA key, dbuf; - key.dptr = "transaction test"; - key.dsize = strlen(key.dptr); + key.dptr = (unsigned char *)"transaction test"; + key.dsize = strlen((char *)key.dptr); dbuf.dptr = (unsigned char *)&r; dbuf.dsize = sizeof(r); tdb_transaction_start(tdb); -- cgit From e381c13b023f2b512b3f6aec133db9f323bc8132 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 27 May 2009 19:25:44 +0200 Subject: s3:idmap_ldap: filter out of range mappings in default idmap config This fixes bug #6417 Michael --- source3/winbindd/idmap_ldap.c | 71 +++++++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 16 deletions(-) diff --git a/source3/winbindd/idmap_ldap.c b/source3/winbindd/idmap_ldap.c index 88ece8c7de..3d1dd488d6 100644 --- a/source3/winbindd/idmap_ldap.c +++ b/source3/winbindd/idmap_ldap.c @@ -765,7 +765,6 @@ static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom, NTSTATUS ret; struct idmap_ldap_context *ctx = NULL; char *config_option = NULL; - const char *range = NULL; const char *tmp = NULL; /* Only do init if we are online */ @@ -779,23 +778,63 @@ static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom, return NT_STATUS_NO_MEMORY; } - config_option = talloc_asprintf(ctx, "idmap config %s", dom->name); - if ( ! config_option) { - DEBUG(0, ("Out of memory!\n")); - ret = NT_STATUS_NO_MEMORY; - goto done; - } + if (strequal(dom->name, "*")) { + uid_t low_uid = 0; + uid_t high_uid = 0; + gid_t low_gid = 0; + gid_t high_gid = 0; - /* load ranges */ - range = lp_parm_const_string(-1, config_option, "range", NULL); - if (range && range[0]) { - if ((sscanf(range, "%u - %u", &ctx->filter_low_id, - &ctx->filter_high_id) != 2) || - (ctx->filter_low_id > ctx->filter_high_id)) { - DEBUG(1, ("ERROR: invalid filter range [%s]", range)); - ctx->filter_low_id = 0; - ctx->filter_high_id = 0; + ctx->filter_low_id = 0; + ctx->filter_high_id = 0; + + if (lp_idmap_uid(&low_uid, &high_uid)) { + ctx->filter_low_id = low_uid; + ctx->filter_high_id = high_uid; + } else { + DEBUG(3, ("Warning: 'idmap uid' not set!\n")); + } + + if (lp_idmap_gid(&low_gid, &high_gid)) { + if ((low_gid != low_uid) || (high_gid != high_uid)) { + DEBUG(1, ("Warning: 'idmap uid' and 'idmap gid'" + " ranges do not agree -- building " + "intersection\n")); + ctx->filter_low_id = MAX(ctx->filter_low_id, + low_gid); + ctx->filter_high_id = MIN(ctx->filter_high_id, + high_gid); + } + } else { + DEBUG(3, ("Warning: 'idmap gid' not set!\n")); + } + } else { + const char *range = NULL; + + config_option = talloc_asprintf(ctx, "idmap config %s", dom->name); + if ( ! config_option) { + DEBUG(0, ("Out of memory!\n")); + ret = NT_STATUS_NO_MEMORY; + goto done; } + + /* load ranges */ + range = lp_parm_const_string(-1, config_option, "range", NULL); + if (range && range[0]) { + if ((sscanf(range, "%u - %u", &ctx->filter_low_id, + &ctx->filter_high_id) != 2)) + { + DEBUG(1, ("ERROR: invalid filter range [%s]", range)); + ctx->filter_low_id = 0; + ctx->filter_high_id = 0; + } + } + } + + if (ctx->filter_low_id > ctx->filter_high_id) { + DEBUG(1, ("ERROR: invalid filter range [%u-%u]", + ctx->filter_low_id, ctx->filter_high_id)); + ctx->filter_low_id = 0; + ctx->filter_high_id = 0; } if (params != NULL) { -- cgit From f55c7614bd7360b484f15c2290ab88195bb78094 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 27 May 2009 17:28:23 -0700 Subject: Add aync POSIX hardlink and symlink and torture test for them. Missing call cli_readlink() is next. Jeremy. --- source3/client/client.c | 4 +- source3/include/proto.h | 20 +- source3/libsmb/clifile.c | 451 ++++++++++++++++++++++++++++++---------------- source3/torture/torture.c | 73 +++++++- 4 files changed, 391 insertions(+), 157 deletions(-) diff --git a/source3/client/client.c b/source3/client/client.c index 13dee6081d..d7c554efc0 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -2725,7 +2725,7 @@ static int cmd_link(void) return 1; } - if (!cli_unix_hardlink(targetcli, targetname, newname)) { + if (!NT_STATUS_IS_OK(cli_posix_hardlink(targetcli, targetname, newname))) { d_printf("%s linking files (%s -> %s)\n", cli_errstr(targetcli), newname, oldname); return 1; } @@ -2776,7 +2776,7 @@ static int cmd_symlink(void) return 1; } - if (!cli_unix_symlink(targetcli, targetname, newname)) { + if (!NT_STATUS_IS_OK(cli_posix_symlink(targetcli, targetname, newname))) { d_printf("%s symlinking files (%s -> %s)\n", cli_errstr(targetcli), newname, targetname); return 1; diff --git a/source3/include/proto.h b/source3/include/proto.h index 717a972505..a918c29aaa 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -2332,12 +2332,28 @@ void cli_reset_error(struct cli_state *cli); /* The following definitions come from libsmb/clifile.c */ +struct tevent_req *cli_posix_symlink_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *oldname, + const char *newname); +NTSTATUS cli_posix_symlink_recv(struct tevent_req *req); +NTSTATUS cli_posix_symlink(struct cli_state *cli, + const char *oldname, + const char *newname); +struct tevent_req *cli_posix_hardlink_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *oldname, + const char *newname); +NTSTATUS cli_posix_hardlink_recv(struct tevent_req *req); +NTSTATUS cli_posix_hardlink(struct cli_state *cli, + const char *oldname, + const char *newname); uint32_t unix_perms_to_wire(mode_t perms); mode_t wire_perms_to_unix(uint32_t perms); bool cli_unix_getfacl(struct cli_state *cli, const char *name, size_t *prb_size, char **retbuf); bool cli_unix_stat(struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbuf); -bool cli_unix_symlink(struct cli_state *cli, const char *oldname, const char *newname); -bool cli_unix_hardlink(struct cli_state *cli, const char *oldname, const char *newname); bool cli_unix_chmod(struct cli_state *cli, const char *fname, mode_t mode); bool cli_unix_chown(struct cli_state *cli, const char *fname, uid_t uid, gid_t gid); struct tevent_req *cli_rename_send(TALLOC_CTX *mem_ctx, diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 1225aa6bae..e48656b698 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -20,74 +20,328 @@ #include "includes.h" +/*********************************************************** + Common function for pushing stings, used by smb_bytes_push_str() + and trans_bytes_push_str(). Only difference is the align_odd + parameter setting. +***********************************************************/ + +static uint8_t *internal_bytes_push_str(uint8_t *buf, bool ucs2, + const char *str, size_t str_len, + bool align_odd, + size_t *pconverted_size) +{ + size_t buflen; + char *converted; + size_t converted_size; + + if (buf == NULL) { + return NULL; + } + + buflen = talloc_get_size(buf); + + if (align_odd && ucs2 && (buflen % 2 == 0)) { + /* + * We're pushing into an SMB buffer, align odd + */ + buf = TALLOC_REALLOC_ARRAY(NULL, buf, uint8_t, buflen + 1); + if (buf == NULL) { + return NULL; + } + buf[buflen] = '\0'; + buflen += 1; + } + + if (!convert_string_talloc(talloc_tos(), CH_UNIX, + ucs2 ? CH_UTF16LE : CH_DOS, + str, str_len, &converted, + &converted_size, true)) { + return NULL; + } + + buf = TALLOC_REALLOC_ARRAY(NULL, buf, uint8_t, + buflen + converted_size); + if (buf == NULL) { + TALLOC_FREE(converted); + return NULL; + } + + memcpy(buf + buflen, converted, converted_size); + + TALLOC_FREE(converted); + + if (pconverted_size) { + *pconverted_size = converted_size; + } + + return buf; +} + +/*********************************************************** + Push a string into an SMB buffer, with odd byte alignment + if it's a UCS2 string. +***********************************************************/ + +uint8_t *smb_bytes_push_str(uint8_t *buf, bool ucs2, + const char *str, size_t str_len, + size_t *pconverted_size) +{ + return internal_bytes_push_str(buf, ucs2, str, str_len, + true, pconverted_size); +} + +/*********************************************************** + Same as smb_bytes_push_str(), but without the odd byte + align for ucs2 (we're pushing into a param or data block). + static for now, although this will probably change when + other modules use async trans calls. +***********************************************************/ + +static uint8_t *trans2_bytes_push_str(uint8_t *buf, bool ucs2, + const char *str, size_t str_len, + size_t *pconverted_size) +{ + return internal_bytes_push_str(buf, ucs2, str, str_len, + false, pconverted_size); +} + + /**************************************************************************** Hard/Symlink a file (UNIX extensions). Creates new name (sym)linked to oldname. ****************************************************************************/ -static bool cli_link_internal(struct cli_state *cli, const char *oldname, const char *newname, bool hard_link) +struct link_state { + uint16_t setup; + uint8_t *param; + uint8_t *data; +}; + +static void cli_posix_link_internal_done(struct tevent_req *subreq) { - unsigned int data_len = 0; - unsigned int param_len = 0; - uint16_t setup = TRANSACT2_SETPATHINFO; - char *param; - char *data; - char *rparam=NULL, *rdata=NULL; - char *p; - size_t oldlen = 2*(strlen(oldname)+1); - size_t newlen = 2*(strlen(newname)+1); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct link_state *state = tevent_req_data(req, struct link_state); + NTSTATUS status; + + status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; + } + tevent_req_done(req); +} - param = SMB_MALLOC_ARRAY(char, 6+newlen+2); +static struct tevent_req *cli_posix_link_internal_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *oldname, + const char *newname, + bool hardlink) +{ + struct tevent_req *req = NULL, *subreq = NULL; + struct link_state *state = NULL; - if (!param) { - return false; + req = tevent_req_create(mem_ctx, &state, struct link_state); + if (req == NULL) { + return NULL; } - data = SMB_MALLOC_ARRAY(char, oldlen+2); + /* Setup setup word. */ + SSVAL(&state->setup, 0, TRANSACT2_SETPATHINFO); - if (!data) { - SAFE_FREE(param); - return false; + /* Setup param array. */ + state->param = talloc_array(state, uint8_t, 6); + if (tevent_req_nomem(state->param, req)) { + return tevent_req_post(req, ev); } + memset(state->param, '\0', 6); + SSVAL(state->param,0,hardlink ? SMB_SET_FILE_UNIX_HLINK : SMB_SET_FILE_UNIX_LINK); - SSVAL(param,0,hard_link ? SMB_SET_FILE_UNIX_HLINK : SMB_SET_FILE_UNIX_LINK); - SIVAL(param,2,0); - p = ¶m[6]; + state->param = trans2_bytes_push_str(state->param, cli_ucs2(cli), newname, + strlen(newname)+1, NULL); - p += clistr_push(cli, p, newname, newlen, STR_TERMINATE); - param_len = PTR_DIFF(p, param); + if (tevent_req_nomem(state->param, req)) { + return tevent_req_post(req, ev); + } - p = data; - p += clistr_push(cli, p, oldname, oldlen, STR_TERMINATE); - data_len = PTR_DIFF(p, data); + /* Setup data array. */ + state->data = talloc_array(state, uint8_t, 0); + if (tevent_req_nomem(state->data, req)) { + return tevent_req_post(req, ev); + } + state->data = trans2_bytes_push_str(state->data, cli_ucs2(cli), oldname, + strlen(oldname)+1, NULL); - if (!cli_send_trans(cli, SMBtrans2, - NULL, /* name */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 2, /* param, length, max */ - data, data_len, cli->max_xmit /* data, length, max */ - )) { - SAFE_FREE(data); - SAFE_FREE(param); - return false; + subreq = cli_trans_send(state, /* mem ctx. */ + ev, /* event ctx. */ + cli, /* cli_state. */ + SMBtrans2, /* cmd. */ + NULL, /* pipe name. */ + -1, /* fid. */ + 0, /* function. */ + 0, /* flags. */ + &state->setup, /* setup. */ + 1, /* num setup uint16_t words. */ + 0, /* max returned setup. */ + state->param, /* param. */ + talloc_get_size(state->param), /* num param. */ + 2, /* max returned param. */ + state->data, /* data. */ + talloc_get_size(state->data), /* num data. */ + 0); /* max returned data. */ + + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); } + tevent_req_set_callback(subreq, cli_posix_link_internal_done, req); + return req; +} - SAFE_FREE(data); - SAFE_FREE(param); +/**************************************************************************** + Symlink a file (UNIX extensions). +****************************************************************************/ - if (!cli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len)) { - return false; +struct tevent_req *cli_posix_symlink_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *oldname, + const char *newname) +{ + return cli_posix_link_internal_send(mem_ctx, ev, cli, + oldname, newname, false); +} + +NTSTATUS cli_posix_symlink_recv(struct tevent_req *req) +{ + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + return status; } + return NT_STATUS_OK; +} - SAFE_FREE(data); - SAFE_FREE(param); - SAFE_FREE(rdata); - SAFE_FREE(rparam); +NTSTATUS cli_posix_symlink(struct cli_state *cli, + const char *oldname, + const char *newname) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev = NULL; + struct tevent_req *req = NULL; + NTSTATUS status = NT_STATUS_OK; - return true; + if (cli_has_async_calls(cli)) { + /* + * Can't use sync call while an async call is in flight + */ + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + + ev = event_context_init(frame); + if (ev == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + req = cli_posix_symlink_send(frame, + ev, + cli, + oldname, + newname); + if (req == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + if (!tevent_req_poll(req, ev)) { + status = map_nt_error_from_unix(errno); + goto fail; + } + + status = cli_posix_symlink_recv(req); + + fail: + TALLOC_FREE(frame); + if (!NT_STATUS_IS_OK(status)) { + cli_set_error(cli, status); + } + return status; +} + +/**************************************************************************** + Hard link a file (UNIX extensions). +****************************************************************************/ + +struct tevent_req *cli_posix_hardlink_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *oldname, + const char *newname) +{ + return cli_posix_link_internal_send(mem_ctx, ev, cli, + oldname, newname, true); +} + +NTSTATUS cli_posix_hardlink_recv(struct tevent_req *req) +{ + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + return status; + } + return NT_STATUS_OK; +} + +NTSTATUS cli_posix_hardlink(struct cli_state *cli, + const char *oldname, + const char *newname) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev = NULL; + struct tevent_req *req = NULL; + NTSTATUS status = NT_STATUS_OK; + + if (cli_has_async_calls(cli)) { + /* + * Can't use sync call while an async call is in flight + */ + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + + ev = event_context_init(frame); + if (ev == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + req = cli_posix_hardlink_send(frame, + ev, + cli, + oldname, + newname); + if (req == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + if (!tevent_req_poll(req, ev)) { + status = map_nt_error_from_unix(errno); + goto fail; + } + + status = cli_posix_hardlink_recv(req); + + fail: + TALLOC_FREE(frame); + if (!NT_STATUS_IS_OK(status)) { + cli_set_error(cli, status); + } + return status; } /**************************************************************************** @@ -325,25 +579,6 @@ bool cli_unix_stat(struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbu return true; } - -/**************************************************************************** - Symlink a file (UNIX extensions). -****************************************************************************/ - -bool cli_unix_symlink(struct cli_state *cli, const char *oldname, const char *newname) -{ - return cli_link_internal(cli, oldname, newname, False); -} - -/**************************************************************************** - Hard a file (UNIX extensions). -****************************************************************************/ - -bool cli_unix_hardlink(struct cli_state *cli, const char *oldname, const char *newname) -{ - return cli_link_internal(cli, oldname, newname, True); -} - /**************************************************************************** Chmod or chown a file internal (UNIX extensions). ****************************************************************************/ @@ -1288,92 +1523,6 @@ NTSTATUS cli_ntcreate(struct cli_state *cli, return status; } -/*********************************************************** - Common function for pushing stings, used by smb_bytes_push_str() - and trans_bytes_push_str(). Only difference is the align_odd - parameter setting. -***********************************************************/ - -static uint8_t *internal_bytes_push_str(uint8_t *buf, bool ucs2, - const char *str, size_t str_len, - bool align_odd, - size_t *pconverted_size) -{ - size_t buflen; - char *converted; - size_t converted_size; - - if (buf == NULL) { - return NULL; - } - - buflen = talloc_get_size(buf); - - if (align_odd && ucs2 && (buflen % 2 == 0)) { - /* - * We're pushing into an SMB buffer, align odd - */ - buf = TALLOC_REALLOC_ARRAY(NULL, buf, uint8_t, buflen + 1); - if (buf == NULL) { - return NULL; - } - buf[buflen] = '\0'; - buflen += 1; - } - - if (!convert_string_talloc(talloc_tos(), CH_UNIX, - ucs2 ? CH_UTF16LE : CH_DOS, - str, str_len, &converted, - &converted_size, true)) { - return NULL; - } - - buf = TALLOC_REALLOC_ARRAY(NULL, buf, uint8_t, - buflen + converted_size); - if (buf == NULL) { - TALLOC_FREE(converted); - return NULL; - } - - memcpy(buf + buflen, converted, converted_size); - - TALLOC_FREE(converted); - - if (pconverted_size) { - *pconverted_size = converted_size; - } - - return buf; -} - -/*********************************************************** - Push a string into an SMB buffer, with odd byte alignment - if it's a UCS2 string. -***********************************************************/ - -uint8_t *smb_bytes_push_str(uint8_t *buf, bool ucs2, - const char *str, size_t str_len, - size_t *pconverted_size) -{ - return internal_bytes_push_str(buf, ucs2, str, str_len, - true, pconverted_size); -} - -/*********************************************************** - Same as smb_bytes_push_str(), but without the odd byte - align for ucs2 (we're pushing into a param or data block). - static for now, although this will probably change when - other modules use async trans calls. -***********************************************************/ - -static uint8_t *trans2_bytes_push_str(uint8_t *buf, bool ucs2, - const char *str, size_t str_len, - size_t *pconverted_size) -{ - return internal_bytes_push_str(buf, ucs2, str, str_len, - false, pconverted_size); -} - /**************************************************************************** Open a file WARNING: if you open with O_WRONLY then getattrE won't work! diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 41343cab87..bff8d07f1f 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -4135,8 +4135,11 @@ static bool run_opentest(int dummy) static bool run_simple_posix_open_test(int dummy) { static struct cli_state *cli1; - const char *fname = "\\posix:file"; - const char *dname = "\\posix:dir"; + const char *fname = "posix:file"; + const char *hname = "posix:hlink"; + const char *sname = "posix:symlink"; + const char *dname = "posix:dir"; + char buf[10]; uint16 major, minor; uint32 caplow, caphigh; uint16_t fnum1 = (uint16_t)-1; @@ -4171,6 +4174,10 @@ static bool run_simple_posix_open_test(int dummy) cli_posix_unlink(cli1, fname); cli_setatr(cli1, dname, 0, 0); cli_posix_rmdir(cli1, dname); + cli_setatr(cli1, hname, 0, 0); + cli_posix_unlink(cli1, hname); + cli_setatr(cli1, sname, 0, 0); + cli_posix_unlink(cli1, sname); /* Create a directory. */ if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1, dname, 0777))) { @@ -4222,6 +4229,64 @@ static bool run_simple_posix_open_test(int dummy) } } + /* Create the file. */ + if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) { + printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1)); + goto out; + } + + /* Write some data into it. */ + if (cli_write(cli1, fnum1, 0, "TEST DATA\n", 0, 10) != 10) { + printf("cli_write failed: %s\n", cli_errstr(cli1)); + goto out; + } + + cli_close(cli1, fnum1); + + /* Now create a hardlink. */ + if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1, fname, hname))) { + printf("POSIX hardlink of %s failed (%s)\n", hname, cli_errstr(cli1)); + goto out; + } + + /* Now create a symlink. */ + if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1, fname, sname))) { + printf("POSIX symlink of %s failed (%s)\n", sname, cli_errstr(cli1)); + goto out; + } + + /* Open the hardlink for read. */ + if (!NT_STATUS_IS_OK(cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1))) { + printf("POSIX open of %s failed (%s)\n", hname, cli_errstr(cli1)); + goto out; + } + + if (cli_read(cli1, fnum1, buf, 0, 10) != 10) { + printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1)); + goto out; + } + + if (memcmp(buf, "TEST DATA\n", 10)) { + printf("invalid data read from hardlink\n"); + goto out; + } + + cli_close(cli1, fnum1); + + /* Open the symlink for read - this should fail. A POSIX + client should not be doing opens on a symlink. */ + if (NT_STATUS_IS_OK(cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1))) { + printf("POSIX open of %s succeeded (should have failed)\n", sname); + goto out; + } else { + if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath, + NT_STATUS_OBJECT_PATH_NOT_FOUND)) { + goto out; + } + } + + /* TODO. Add and test cli_posix_readlink() call. */ + if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1, dname))) { printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1)); goto out; @@ -4237,6 +4302,10 @@ static bool run_simple_posix_open_test(int dummy) fnum1 = (uint16_t)-1; } + cli_setatr(cli1, sname, 0, 0); + cli_posix_unlink(cli1, sname); + cli_setatr(cli1, hname, 0, 0); + cli_posix_unlink(cli1, hname); cli_setatr(cli1, fname, 0, 0); cli_posix_unlink(cli1, fname); cli_setatr(cli1, dname, 0, 0); -- cgit From bccc7ee2c6456cdab08884b826ed5ddc2faf2a54 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 27 May 2009 21:51:15 -0700 Subject: Add cli_posix_readlink() and a torture test for it. Jeremy. --- source3/include/proto.h | 9 +++ source3/libsmb/clifile.c | 184 +++++++++++++++++++++++++++++++++++++++++++++- source3/torture/torture.c | 16 +++- 3 files changed, 207 insertions(+), 2 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index a918c29aaa..342c1432eb 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -2341,6 +2341,15 @@ NTSTATUS cli_posix_symlink_recv(struct tevent_req *req); NTSTATUS cli_posix_symlink(struct cli_state *cli, const char *oldname, const char *newname); +struct tevent_req *cli_posix_readlink_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname, + size_t len); +NTSTATUS cli_posix_readlink_recv(struct tevent_req *req, struct cli_state *cli, + char *retpath, size_t len); +NTSTATUS cli_posix_readlink(struct cli_state *cli, const char *fname, + char *linkpath, size_t len); struct tevent_req *cli_posix_hardlink_send(TALLOC_CTX *mem_ctx, struct event_context *ev, struct cli_state *cli, diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index e48656b698..187fcdf625 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -106,7 +106,6 @@ static uint8_t *trans2_bytes_push_str(uint8_t *buf, bool ucs2, false, pconverted_size); } - /**************************************************************************** Hard/Symlink a file (UNIX extensions). Creates new name (sym)linked to oldname. @@ -272,6 +271,189 @@ NTSTATUS cli_posix_symlink(struct cli_state *cli, return status; } +/**************************************************************************** + Read a POSIX symlink. +****************************************************************************/ + +struct readlink_state { + uint16_t setup; + uint8_t *param; + uint8_t *data; + uint32_t num_data; +}; + +static void cli_posix_readlink_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct readlink_state *state = tevent_req_data(req, struct readlink_state); + NTSTATUS status; + + status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, + &state->data, &state->num_data); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; + } + if (state->num_data == 0) { + tevent_req_nterror(req, NT_STATUS_DATA_ERROR); + return; + } + if (state->data[state->num_data-1] != '\0') { + tevent_req_nterror(req, NT_STATUS_DATA_ERROR); + return; + } + tevent_req_done(req); +} + +struct tevent_req *cli_posix_readlink_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname, + size_t len) +{ + struct tevent_req *req = NULL, *subreq = NULL; + struct readlink_state *state = NULL; + uint32_t maxbytelen = (uint32_t)(cli_ucs2(cli) ? len*3 : len); + + if (maxbytelen < len) { + return NULL; + } + + req = tevent_req_create(mem_ctx, &state, struct readlink_state); + if (req == NULL) { + return NULL; + } + + /* Setup setup word. */ + SSVAL(&state->setup, 0, TRANSACT2_QPATHINFO); + + /* Setup param array. */ + state->param = talloc_array(state, uint8_t, 6); + if (tevent_req_nomem(state->param, req)) { + return tevent_req_post(req, ev); + } + memset(state->param, '\0', 6); + SSVAL(state->param,0,SMB_QUERY_FILE_UNIX_LINK); + + state->param = trans2_bytes_push_str(state->param, cli_ucs2(cli), fname, + strlen(fname)+1, NULL); + + if (tevent_req_nomem(state->param, req)) { + return tevent_req_post(req, ev); + } + + subreq = cli_trans_send(state, /* mem ctx. */ + ev, /* event ctx. */ + cli, /* cli_state. */ + SMBtrans2, /* cmd. */ + NULL, /* pipe name. */ + -1, /* fid. */ + 0, /* function. */ + 0, /* flags. */ + &state->setup, /* setup. */ + 1, /* num setup uint16_t words. */ + 0, /* max returned setup. */ + state->param, /* param. */ + talloc_get_size(state->param), /* num param. */ + 2, /* max returned param. */ + NULL, /* data. */ + 0, /* num data. */ + maxbytelen); /* max returned data. */ + + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, cli_posix_readlink_done, req); + return req; +} + +NTSTATUS cli_posix_readlink_recv(struct tevent_req *req, struct cli_state *cli, + char *retpath, size_t len) +{ + NTSTATUS status; + char *converted = NULL; + size_t converted_size = 0; + struct readlink_state *state = tevent_req_data(req, struct readlink_state); + + if (tevent_req_is_nterror(req, &status)) { + return status; + } + /* The returned data is a pushed string, not raw data. */ + if (!convert_string_talloc(state, + cli_ucs2(cli) ? CH_UTF16LE : CH_DOS, + CH_UNIX, + state->data, + state->num_data, + &converted, + &converted_size, + true)) { + return NT_STATUS_NO_MEMORY; + } + + len = MIN(len,converted_size); + if (len == 0) { + return NT_STATUS_DATA_ERROR; + } + memcpy(retpath, converted, len); + return NT_STATUS_OK; +} + +NTSTATUS cli_posix_readlink(struct cli_state *cli, const char *fname, + char *linkpath, size_t len) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev = NULL; + struct tevent_req *req = NULL; + NTSTATUS status = NT_STATUS_OK; + + if (cli_has_async_calls(cli)) { + /* + * Can't use sync call while an async call is in flight + */ + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + + ev = event_context_init(frame); + if (ev == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + /* Len is in bytes, we need it in UCS2 units. */ + if (2*len < len) { + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + + req = cli_posix_readlink_send(frame, + ev, + cli, + fname, + len); + if (req == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + if (!tevent_req_poll(req, ev)) { + status = map_nt_error_from_unix(errno); + goto fail; + } + + status = cli_posix_readlink_recv(req, cli, linkpath, len); + + fail: + TALLOC_FREE(frame); + if (!NT_STATUS_IS_OK(status)) { + cli_set_error(cli, status); + } + return status; +} + + /**************************************************************************** Hard link a file (UNIX extensions). ****************************************************************************/ diff --git a/source3/torture/torture.c b/source3/torture/torture.c index bff8d07f1f..b05ca44f0e 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -4140,6 +4140,7 @@ static bool run_simple_posix_open_test(int dummy) const char *sname = "posix:symlink"; const char *dname = "posix:dir"; char buf[10]; + char namebuf[11]; uint16 major, minor; uint32 caplow, caphigh; uint16_t fnum1 = (uint16_t)-1; @@ -4281,11 +4282,24 @@ static bool run_simple_posix_open_test(int dummy) } else { if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND)) { + printf("POSIX open of %s should have failed " + "with NT_STATUS_OBJECT_PATH_NOT_FOUND, " + "failed with %s instead.\n", + sname, cli_errstr(cli1)); goto out; } } - /* TODO. Add and test cli_posix_readlink() call. */ + if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf)))) { + printf("POSIX readlink on %s failed (%s)\n", sname, cli_errstr(cli1)); + goto out; + } + + if (strcmp(namebuf, fname) != 0) { + printf("POSIX readlink on %s failed to match name %s (read %s)\n", + sname, fname, namebuf); + goto out; + } if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1, dname))) { printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1)); -- cgit From bd1194810787901c5caa08961f97fecbcbd01978 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 27 May 2009 22:02:20 -0700 Subject: Add a smbclient "readlink" command and add docs for it. Jeremy. --- docs-xml/manpages-3/smbclient.1.xml | 8 ++++++ source3/client/client.c | 49 +++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/docs-xml/manpages-3/smbclient.1.xml b/docs-xml/manpages-3/smbclient.1.xml index 7785d2c093..9840414e44 100644 --- a/docs-xml/manpages-3/smbclient.1.xml +++ b/docs-xml/manpages-3/smbclient.1.xml @@ -915,6 +915,14 @@ See the exit command. + + readlink symlinkname + This command depends on the server supporting the CIFS + UNIX extensions and will fail if the server does not. Print + the value of the symlink "symlinkname". + + + rd <directory name> See the rmdir command. diff --git a/source3/client/client.c b/source3/client/client.c index d7c554efc0..2edeb1ae2b 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -2732,6 +2732,54 @@ static int cmd_link(void) return 0; } +/**************************************************************************** + UNIX readlink. +****************************************************************************/ + +static int cmd_readlink(void) +{ + TALLOC_CTX *ctx = talloc_tos(); + char *name= NULL; + char *buf = NULL; + char *targetname = NULL; + char linkname[PATH_MAX+1]; + struct cli_state *targetcli; + + if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { + d_printf("readlink \n"); + return 1; + } + name = talloc_asprintf(ctx, + "%s%s", + client_get_cur_dir(), + buf); + if (!name) { + return 1; + } + + if (!cli_resolve_path(ctx, "", auth_info, cli, name, &targetcli, &targetname)) { + d_printf("readlink %s: %s\n", name, cli_errstr(cli)); + return 1; + } + + if (!SERVER_HAS_UNIX_CIFS(targetcli)) { + d_printf("Server doesn't support UNIX CIFS calls.\n"); + return 1; + } + + if (!NT_STATUS_IS_OK(cli_posix_readlink(targetcli, name, + linkname, PATH_MAX+1))) { + d_printf("%s readlink on file %s\n", + cli_errstr(targetcli), name); + return 1; + } + + d_printf("%s -> %s\n", name, linkname); + + return 0; +} + + /**************************************************************************** UNIX symlink. ****************************************************************************/ @@ -3953,6 +4001,7 @@ static struct { {"q",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}}, {"queue",cmd_queue,"show the print queue",{COMPL_NONE,COMPL_NONE}}, {"quit",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}}, + {"readlink",cmd_readlink,"filename Do a UNIX extensions readlink call on a symlink",{COMPL_REMOTE,COMPL_REMOTE}}, {"rd",cmd_rmdir," remove a directory",{COMPL_NONE,COMPL_NONE}}, {"recurse",cmd_recurse,"toggle directory recursion for mget and mput",{COMPL_NONE,COMPL_NONE}}, {"reget",cmd_reget," [local name] get a file restarting at end of local file",{COMPL_REMOTE,COMPL_LOCAL}}, -- cgit