From 69d8c5ae5f1319e3c9430aa7d6d09ca2a62ba10a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 1 Feb 2007 19:29:07 +0000 Subject: r21115: notify_internal.c needs to remove the table entry if a process has crashed. So it needs the specific error message. Make messages.c return NTSTATUS and specificially NT_STATUS_INVALID_HANDLE if sending to a non-existent process. Volker (This used to be commit 3f620d181da0c356c8ffbdb5b380ccab3645a972) --- source3/lib/messages.c | 100 +++++++++++++++++++++++-------------- source3/libsmb/clidgram.c | 5 +- source3/rpc_server/srv_srvsvc_nt.c | 2 +- source3/smbd/open.c | 11 ++-- source3/utils/smbcontrol.c | 3 +- 5 files changed, 74 insertions(+), 47 deletions(-) diff --git a/source3/lib/messages.c b/source3/lib/messages.c index 5bf1774af1..e0bf86a46c 100644 --- a/source3/lib/messages.c +++ b/source3/lib/messages.c @@ -166,7 +166,7 @@ static TDB_DATA message_key_pid(struct process_id pid) then delete its record in the database. ****************************************************************************/ -static BOOL message_notify(struct process_id procid) +static NTSTATUS message_notify(struct process_id procid) { pid_t pid = procid.pid; int ret; @@ -191,25 +191,40 @@ static BOOL message_notify(struct process_id procid) if (ret == -1) { if (errno == ESRCH) { - DEBUG(2,("pid %d doesn't exist - deleting messages record\n", (int)pid)); + DEBUG(2,("pid %d doesn't exist - deleting messages record\n", + (int)pid)); tdb_delete(tdb, message_key_pid(procid)); - } else { - DEBUG(2,("message to process %d failed - %s\n", (int)pid, strerror(errno))); + + /* + * INVALID_HANDLE is the closest I can think of -- vl + */ + return NT_STATUS_INVALID_HANDLE; } - return False; + + DEBUG(2,("message to process %d failed - %s\n", (int)pid, + strerror(errno))); + + /* + * No call to map_nt_error_from_unix -- don't want to link in + * errormap.o into lots of utils. + */ + + if (errno == EINVAL) return NT_STATUS_INVALID_PARAMETER; + if (errno == EPERM) return NT_STATUS_ACCESS_DENIED; + return NT_STATUS_UNSUCCESSFUL; } - return True; + return NT_STATUS_OK; } /**************************************************************************** Send a message to a particular pid. ****************************************************************************/ -static BOOL message_send_pid_internal(struct process_id pid, int msg_type, - const void *buf, size_t len, - BOOL duplicates_allowed, - unsigned int timeout) +static NTSTATUS message_send_pid_internal(struct process_id pid, int msg_type, + const void *buf, size_t len, + BOOL duplicates_allowed, + unsigned int timeout) { TDB_DATA kbuf; TDB_DATA dbuf; @@ -239,8 +254,9 @@ static BOOL message_send_pid_internal(struct process_id pid, int msg_type, kbuf = message_key_pid(pid); dbuf.dptr = (char *)SMB_MALLOC(len + sizeof(rec)); - if (!dbuf.dptr) - return False; + if (!dbuf.dptr) { + return NT_STATUS_NO_MEMORY; + } memcpy(dbuf.dptr, &rec, sizeof(rec)); if (len > 0 && buf) @@ -255,13 +271,15 @@ static BOOL message_send_pid_internal(struct process_id pid, int msg_type, /* lock the record for the destination */ if (timeout) { if (tdb_chainlock_with_timeout(tdb, kbuf, timeout) == -1) { - DEBUG(0,("message_send_pid_internal: failed to get chainlock with timeout %ul.\n", timeout)); - return False; + DEBUG(0,("message_send_pid_internal: failed to get " + "chainlock with timeout %ul.\n", timeout)); + return NT_STATUS_IO_TIMEOUT; } } else { if (tdb_chainlock(tdb, kbuf) == -1) { - DEBUG(0,("message_send_pid_internal: failed to get chainlock.\n")); - return False; + DEBUG(0,("message_send_pid_internal: failed to get " + "chainlock.\n")); + return NT_STATUS_LOCK_NOT_GRANTED; } } tdb_append(tdb, kbuf, dbuf); @@ -275,13 +293,15 @@ static BOOL message_send_pid_internal(struct process_id pid, int msg_type, /* lock the record for the destination */ if (timeout) { if (tdb_chainlock_with_timeout(tdb, kbuf, timeout) == -1) { - DEBUG(0,("message_send_pid_internal: failed to get chainlock with timeout %ul.\n", timeout)); - return False; + DEBUG(0,("message_send_pid_internal: failed to get chainlock " + "with timeout %ul.\n", timeout)); + return NT_STATUS_IO_TIMEOUT; } } else { if (tdb_chainlock(tdb, kbuf) == -1) { - DEBUG(0,("message_send_pid_internal: failed to get chainlock.\n")); - return False; + DEBUG(0,("message_send_pid_internal: failed to get " + "chainlock.\n")); + return NT_STATUS_LOCK_NOT_GRANTED; } } @@ -310,10 +330,11 @@ static BOOL message_send_pid_internal(struct process_id pid, int msg_type, if (!memcmp(ptr, &rec, sizeof(rec))) { if (!len || (len && !memcmp( ptr + sizeof(rec), buf, len))) { tdb_chainunlock(tdb, kbuf); - DEBUG(10,("message_send_pid_internal: discarding duplicate message.\n")); + DEBUG(10,("message_send_pid_internal: discarding " + "duplicate message.\n")); SAFE_FREE(dbuf.dptr); SAFE_FREE(old_dbuf.dptr); - return True; + return NT_STATUS_OK; } } memcpy(&prec, ptr, sizeof(prec)); @@ -336,19 +357,23 @@ static BOOL message_send_pid_internal(struct process_id pid, int msg_type, Send a message to a particular pid - no timeout. ****************************************************************************/ -BOOL message_send_pid(struct process_id pid, int msg_type, const void *buf, size_t len, BOOL duplicates_allowed) +NTSTATUS message_send_pid(struct process_id pid, int msg_type, const void *buf, + size_t len, BOOL duplicates_allowed) { - return message_send_pid_internal(pid, msg_type, buf, len, duplicates_allowed, 0); + return message_send_pid_internal(pid, msg_type, buf, len, + duplicates_allowed, 0); } /**************************************************************************** Send a message to a particular pid, with timeout in seconds. ****************************************************************************/ -BOOL message_send_pid_with_timeout(struct process_id pid, int msg_type, const void *buf, size_t len, - BOOL duplicates_allowed, unsigned int timeout) +NTSTATUS message_send_pid_with_timeout(struct process_id pid, int msg_type, + const void *buf, size_t len, + BOOL duplicates_allowed, unsigned int timeout) { - return message_send_pid_internal(pid, msg_type, buf, len, duplicates_allowed, timeout); + return message_send_pid_internal(pid, msg_type, buf, len, duplicates_allowed, + timeout); } /**************************************************************************** @@ -586,6 +611,7 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void { struct connections_data crec; struct msg_all *msg_all = (struct msg_all *)state; + NTSTATUS status; if (dbuf.dsize != sizeof(crec)) return 0; @@ -603,18 +629,17 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void /* If the msg send fails because the pid was not found (i.e. smbd died), * the msg has already been deleted from the messages.tdb.*/ - if (!message_send_pid(crec.pid, msg_all->msg_type, - msg_all->buf, msg_all->len, - msg_all->duplicates)) { + status = message_send_pid(crec.pid, msg_all->msg_type, + msg_all->buf, msg_all->len, + msg_all->duplicates); + + if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) { /* If the pid was not found delete the entry from connections.tdb */ - if (errno == ESRCH) { - DEBUG(2,("pid %s doesn't exist - deleting connections %d [%s]\n", - procid_str_static(&crec.pid), - crec.cnum, crec.name)); - tdb_delete(the_tdb, kbuf); - } + DEBUG(2,("pid %s doesn't exist - deleting connections %d [%s]\n", + procid_str_static(&crec.pid), crec.cnum, crec.name)); + tdb_delete(the_tdb, kbuf); } msg_all->n_sent++; return 0; @@ -806,8 +831,7 @@ NTSTATUS messaging_send(struct messaging_context *msg, uint32_t msg_type, DATA_BLOB *data) { return message_send_pid_internal(server.id, msg_type, data->data, - data->length, True, 0) - ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED; + data->length, True, 0); } /** @} **/ diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index dfb613238f..a983f485ab 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -101,8 +101,9 @@ BOOL cli_send_mailslot(BOOL unique, const char *mailslot, DEBUGADD(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), inet_ntoa(dest_ip))); - return message_send_pid(pid_to_procid(nmbd_pid), MSG_SEND_PACKET, &p, sizeof(p), - False); + return NT_STATUS_IS_OK(message_send_pid(pid_to_procid(nmbd_pid), + MSG_SEND_PACKET, &p, sizeof(p), + False)); } /* diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c index 3dea0a8493..c0953f2723 100644 --- a/source3/rpc_server/srv_srvsvc_nt.c +++ b/source3/rpc_server/srv_srvsvc_nt.c @@ -1219,7 +1219,7 @@ WERROR _srvsvc_NetSessDel(pipes_struct *p, struct srvsvc_NetSessDel *r) if ((strequal(session_list[snum].username, r->in.user) || r->in.user[0] == '\0' ) && strequal(session_list[snum].remote_machine, machine)) { - if (message_send_pid(pid_to_procid(session_list[snum].pid), MSG_SHUTDOWN, NULL, 0, False)) + if (NT_STATUS_IS_OK(message_send_pid(pid_to_procid(session_list[snum].pid), MSG_SHUTDOWN, NULL, 0, False))) status = WERR_OK; } } diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 6de620e488..2415433fe9 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -652,7 +652,7 @@ static BOOL delay_for_oplocks(struct share_mode_lock *lck, BOOL valid_entry = False; BOOL delay_it = False; BOOL have_level2 = False; - BOOL ret; + NTSTATUS status; char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE]; if (oplock_request & INTERNAL_OPEN_ONLY) { @@ -740,10 +740,11 @@ static BOOL delay_for_oplocks(struct share_mode_lock *lck, SSVAL(msg,6,exclusive->op_type | FORCE_OPLOCK_BREAK_TO_NONE); } - ret = message_send_pid(exclusive->pid, MSG_SMB_BREAK_REQUEST, - msg, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True); - if (!ret) { - DEBUG(3, ("Could not send oplock break message\n")); + status = message_send_pid(exclusive->pid, MSG_SMB_BREAK_REQUEST, + msg, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(3, ("Could not send oplock break message: %s\n", + nt_errstr(status))); } return True; diff --git a/source3/utils/smbcontrol.c b/source3/utils/smbcontrol.c index 26e2b82ae6..ec1e101e06 100644 --- a/source3/utils/smbcontrol.c +++ b/source3/utils/smbcontrol.c @@ -59,7 +59,8 @@ static BOOL send_message(struct process_id pid, int msg_type, return False; if (procid_to_pid(&pid) != 0) - return message_send_pid(pid, msg_type, buf, len, duplicates); + return NT_STATUS_IS_OK(message_send_pid(pid, msg_type, buf, len, + duplicates)); tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_DEFAULT, O_RDWR, 0); -- cgit