-
-static bool serverid_rec_parse(const struct db_record *rec,
- struct server_id *id, uint32_t *msg_flags)
-{
- struct serverid_key key;
- struct serverid_data data;
- TDB_DATA tdbkey;
- TDB_DATA tdbdata;
-
- tdbkey = dbwrap_record_get_key(rec);
- tdbdata = dbwrap_record_get_value(rec);
-
- if (tdbkey.dsize != sizeof(key)) {
- DEBUG(1, ("Found invalid key length %d in serverid.tdb\n",
- (int)tdbkey.dsize));
- return false;
- }
- if (tdbdata.dsize != sizeof(data)) {
- DEBUG(1, ("Found invalid value length %d in serverid.tdb\n",
- (int)tdbdata.dsize));
- return false;
- }
-
- memcpy(&key, tdbkey.dptr, sizeof(key));
- memcpy(&data, tdbdata.dptr, sizeof(data));
-
- id->pid = key.pid;
- id->task_id = key.task_id;
- id->vnn = key.vnn;
- id->unique_id = data.unique_id;
- *msg_flags = data.msg_flags;
- return true;
-}
-
-struct serverid_traverse_read_state {
- int (*fn)(const struct server_id *id, uint32_t msg_flags,
- void *private_data);
- void *private_data;
-};
-
-static int serverid_traverse_read_fn(struct db_record *rec, void *private_data)
-{
- struct serverid_traverse_read_state *state =
- (struct serverid_traverse_read_state *)private_data;
- struct server_id id;
- uint32_t msg_flags;
-
- if (!serverid_rec_parse(rec, &id, &msg_flags)) {
- return 0;
- }
- return state->fn(&id, msg_flags,state->private_data);
-}
-
-bool serverid_traverse_read(int (*fn)(const struct server_id *id,
- uint32_t msg_flags, void *private_data),
- void *private_data)
-{
- struct db_context *db;
- struct serverid_traverse_read_state state;
- NTSTATUS status;
-
- db = serverid_db();
- if (db == NULL) {
- return false;
- }
- state.fn = fn;
- state.private_data = private_data;
-
- status = dbwrap_traverse_read(db, serverid_traverse_read_fn, &state,
- NULL);
- return NT_STATUS_IS_OK(status);
-}
-
-struct serverid_traverse_state {
- int (*fn)(struct db_record *rec, const struct server_id *id,
- uint32_t msg_flags, void *private_data);
- void *private_data;
-};
-
-static int serverid_traverse_fn(struct db_record *rec, void *private_data)
-{
- struct serverid_traverse_state *state =
- (struct serverid_traverse_state *)private_data;
- struct server_id id;
- uint32_t msg_flags;
-
- if (!serverid_rec_parse(rec, &id, &msg_flags)) {
- return 0;
- }
- return state->fn(rec, &id, msg_flags, state->private_data);
-}
-
-bool serverid_traverse(int (*fn)(struct db_record *rec,
- const struct server_id *id,
- uint32_t msg_flags, void *private_data),
- void *private_data)
-{
- struct db_context *db;
- struct serverid_traverse_state state;
- NTSTATUS status;
-
- db = serverid_db();
- if (db == NULL) {
- return false;
- }
- state.fn = fn;
- state.private_data = private_data;
-
- status = dbwrap_traverse(db, serverid_traverse_fn, &state, NULL);
- return NT_STATUS_IS_OK(status);
-}
-
-struct msg_all {
- struct messaging_context *msg_ctx;
- int msg_type;
- uint32_t msg_flag;
- const void *buf;
- size_t len;
- int n_sent;
-};
-
-/****************************************************************************
- Send one of the messages for the broadcast.
-****************************************************************************/
-
-static int traverse_fn(struct db_record *rec, const struct server_id *id,
- uint32_t msg_flags, void *state)
-{
- struct msg_all *msg_all = (struct msg_all *)state;
- NTSTATUS status;
-
- /* Don't send if the receiver hasn't registered an interest. */
-
- if((msg_flags & msg_all->msg_flag) == 0) {
- return 0;
- }
-
- /* 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.*/
-
- status = messaging_send_buf(msg_all->msg_ctx, *id, msg_all->msg_type,
- (const uint8_t *)msg_all->buf, msg_all->len);
-
- if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
- struct server_id_buf idbuf;
-
- /*
- * If the pid was not found delete the entry from
- * serverid.tdb
- */
-
- DEBUG(2, ("pid %s doesn't exist\n",
- server_id_str_buf(*id, &idbuf)));
-
- dbwrap_record_delete(rec);
- }
- msg_all->n_sent++;
- return 0;
-}
-
-/**
- * Send a message to all smbd processes.
- *
- * It isn't very efficient, but should be OK for the sorts of
- * applications that use it. When we need efficient broadcast we can add
- * it.
- *
- * @retval True for success.
- **/
-bool message_send_all(struct messaging_context *msg_ctx,
- int msg_type,
- const void *buf, size_t len)
-{
- struct msg_all msg_all;
-
- msg_all.msg_type = msg_type;
- if (msg_type < 0x100) {
- msg_all.msg_flag = FLAG_MSG_GENERAL;
- } else if (msg_type > 0x100 && msg_type < 0x200) {
- msg_all.msg_flag = FLAG_MSG_NMBD;
- } else if (msg_type > 0x200 && msg_type < 0x300) {
- msg_all.msg_flag = FLAG_MSG_PRINT_GENERAL;
- } else if (msg_type > 0x300 && msg_type < 0x400) {
- msg_all.msg_flag = FLAG_MSG_SMBD;
- } else if (msg_type > 0x400 && msg_type < 0x600) {
- msg_all.msg_flag = FLAG_MSG_WINBIND;
- } else if (msg_type > 4000 && msg_type < 5000) {
- msg_all.msg_flag = FLAG_MSG_DBWRAP;
- } else {
- return false;
- }
-
- msg_all.buf = buf;
- msg_all.len = len;
- msg_all.n_sent = 0;
- msg_all.msg_ctx = msg_ctx;
-
- serverid_traverse(traverse_fn, &msg_all);
- return true;
-}