void msg_close_file(struct messaging_context *msg_ctx, void *private_data, uint32_t msg_type, struct server_id server_id, DATA_BLOB *data) { files_struct *fsp = NULL; struct share_mode_entry e; struct smbd_server_connection *sconn = talloc_get_type_abort(private_data, struct smbd_server_connection); message_to_share_mode_entry(&e, (char *)data->data); if(DEBUGLVL(10)) { char *sm_str = share_mode_str(NULL, 0, &e); if (!sm_str) { smb_panic("talloc failed"); } DEBUG(10,("msg_close_file: got request to close share mode " "entry %s\n", sm_str)); TALLOC_FREE(sm_str); } fsp = file_find_dif(sconn, e.id, e.share_file_id); if (!fsp) { DEBUG(10,("msg_close_file: failed to find file.\n")); return; } close_file(NULL, fsp, NORMAL_CLOSE); }
static void print_share_mode_table(struct locking_data *data) { int num_share_modes = data->u.num_share_mode_entries; share_mode_entry *shares = (share_mode_entry *)(data + 1); int i; for (i = 0; i < num_share_modes; i++) { share_mode_entry *entry_p = &shares[i]; DEBUG(10,("print_share_mode_table: %s\n", share_mode_str(i, entry_p) )); } }
static void print_share_mode_table(struct locking_data *data) { int num_share_modes = data->u.s.num_share_mode_entries; struct share_mode_entry *shares = (struct share_mode_entry *)(data + 1); int i; for (i = 0; i < num_share_modes; i++) { struct share_mode_entry entry; memcpy(&entry, &shares[i], sizeof(struct share_mode_entry)); DEBUG(10,("print_share_mode_table: %s\n", share_mode_str(i, &entry))); } }
static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck) { struct locking_data *data; int i; if (dbuf.dsize < sizeof(struct locking_data)) { smb_panic("PANIC: parse_share_modes: buffer too short.\n"); } data = (struct locking_data *)dbuf.dptr; lck->delete_on_close = data->u.s.delete_on_close; lck->initial_delete_on_close = data->u.s.initial_delete_on_close; lck->num_share_modes = data->u.s.num_share_mode_entries; DEBUG(10, ("parse_share_modes: delete_on_close: %d, " "initial_delete_on_close: %d, " "num_share_modes: %d\n", lck->delete_on_close, lck->initial_delete_on_close, lck->num_share_modes)); if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) { DEBUG(0, ("invalid number of share modes: %d\n", lck->num_share_modes)); smb_panic("PANIC: invalid number of share modes"); } lck->share_modes = NULL; if (lck->num_share_modes != 0) { if (dbuf.dsize < (sizeof(struct locking_data) + (lck->num_share_modes * sizeof(struct share_mode_entry)))) { smb_panic("PANIC: parse_share_modes: buffer too short.\n"); } lck->share_modes = talloc_memdup(lck, dbuf.dptr+sizeof(*data), lck->num_share_modes * sizeof(struct share_mode_entry)); if (lck->share_modes == NULL) { smb_panic("talloc failed\n"); } } /* Get any delete token. */ if (data->u.s.delete_token_size) { char *p = dbuf.dptr + sizeof(*data) + (lck->num_share_modes * sizeof(struct share_mode_entry)); if ((data->u.s.delete_token_size < sizeof(uid_t) + sizeof(gid_t)) || ((data->u.s.delete_token_size - sizeof(uid_t)) % sizeof(gid_t)) != 0) { DEBUG(0, ("parse_share_modes: invalid token size %d\n", data->u.s.delete_token_size)); smb_panic("parse_share_modes: invalid token size\n"); } lck->delete_token = TALLOC_P(lck, UNIX_USER_TOKEN); if (!lck->delete_token) { smb_panic("talloc failed\n"); } /* Copy out the uid and gid. */ memcpy(&lck->delete_token->uid, p, sizeof(uid_t)); p += sizeof(uid_t); memcpy(&lck->delete_token->gid, p, sizeof(gid_t)); p += sizeof(gid_t); /* Any supplementary groups ? */ lck->delete_token->ngroups = (data->u.s.delete_token_size > (sizeof(uid_t) + sizeof(gid_t))) ? ((data->u.s.delete_token_size - (sizeof(uid_t) + sizeof(gid_t)))/sizeof(gid_t)) : 0; if (lck->delete_token->ngroups) { /* Make this a talloc child of lck->delete_token. */ lck->delete_token->groups = TALLOC_ARRAY(lck->delete_token, gid_t, lck->delete_token->ngroups); if (!lck->delete_token) { smb_panic("talloc failed\n"); } for (i = 0; i < lck->delete_token->ngroups; i++) { memcpy(&lck->delete_token->groups[i], p, sizeof(gid_t)); p += sizeof(gid_t); } } } else { lck->delete_token = NULL; } /* Save off the associated service path and filename. */ lck->servicepath = talloc_strdup(lck, dbuf.dptr + sizeof(*data) + (lck->num_share_modes * sizeof(struct share_mode_entry)) + data->u.s.delete_token_size ); lck->filename = talloc_strdup(lck, dbuf.dptr + sizeof(*data) + (lck->num_share_modes * sizeof(struct share_mode_entry)) + data->u.s.delete_token_size + strlen(lck->servicepath) + 1 ); /* * Ensure that each entry has a real process attached. */ for (i = 0; i < lck->num_share_modes; i++) { struct share_mode_entry *entry_p = &lck->share_modes[i]; DEBUG(10,("parse_share_modes: %s\n", share_mode_str(i, entry_p) )); if (!process_exists(entry_p->pid)) { DEBUG(10,("parse_share_modes: deleted %s\n", share_mode_str(i, entry_p) )); entry_p->op_type = UNUSED_SHARE_MODE_ENTRY; lck->modified = True; } } return True; }
ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *entry, share_mode_entry **ppse) { TDB_DATA dbuf; struct locking_data *data; int i, del_count=0; share_mode_entry *shares; ssize_t count = 0; if (ppse) *ppse = NULL; /* read in the existing share modes */ dbuf = tdb_fetch(tdb, locking_key(dev, inode)); if (!dbuf.dptr) return -1; data = (struct locking_data *)dbuf.dptr; shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data)); /* * Find any with this pid and delete it * by overwriting with the rest of the data * from the record. */ DEBUG(10,("del_share_entry: num_share_modes = %d\n", data->u.num_share_mode_entries )); for (i=0;i<data->u.num_share_mode_entries;) { if (share_modes_identical(&shares[i], entry)) { DEBUG(10,("del_share_entry: deleted %s\n", share_mode_str(i, &shares[i]) )); if (ppse) *ppse = memdup(&shares[i], sizeof(*shares)); data->u.num_share_mode_entries--; memmove(&shares[i], &shares[i+1], dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares))); del_count++; DEBUG(10,("del_share_entry: deleting entry %d\n", i )); } else { i++; } } if (del_count) { /* the record may have shrunk a bit */ dbuf.dsize -= del_count * sizeof(*shares); count = (ssize_t)data->u.num_share_mode_entries; /* store it back in the database */ if (data->u.num_share_mode_entries == 0) { if (tdb_delete(tdb, locking_key(dev, inode)) == -1) count = -1; } else { if (tdb_store(tdb, locking_key(dev, inode), dbuf, TDB_REPLACE) == -1) count = -1; } } DEBUG(10,("del_share_entry: Remaining table.\n")); print_share_mode_table((struct locking_data *)dbuf.dptr); SAFE_FREE(dbuf.dptr); return count; }
int get_share_modes(connection_struct *conn, SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry **pp_shares) { TDB_DATA dbuf; struct locking_data *data; int num_share_modes; share_mode_entry *shares = NULL; *pp_shares = NULL; dbuf = tdb_fetch(tdb, locking_key(dev, inode)); if (!dbuf.dptr) return 0; data = (struct locking_data *)dbuf.dptr; num_share_modes = data->u.num_share_mode_entries; if(num_share_modes) { int i; int del_count = 0; shares = (share_mode_entry *)memdup(dbuf.dptr + sizeof(*data), num_share_modes * sizeof(share_mode_entry)); if (!shares) { SAFE_FREE(dbuf.dptr); return 0; } /* * Ensure that each entry has a real process attached. */ for (i = 0; i < num_share_modes; ) { share_mode_entry *entry_p = &shares[i]; if (process_exists(entry_p->pid)) { DEBUG(10,("get_share_modes: %s\n", share_mode_str(i, entry_p) )); i++; } else { DEBUG(10,("get_share_modes: deleted %s\n", share_mode_str(i, entry_p) )); memcpy( &shares[i], &shares[i+1], sizeof(share_mode_entry) * (num_share_modes - i - 1)); num_share_modes--; del_count++; } } /* Did we delete any ? If so, re-store in tdb. */ if (del_count) { data->u.num_share_mode_entries = num_share_modes; if (num_share_modes) memcpy(dbuf.dptr + sizeof(*data), shares, num_share_modes * sizeof(share_mode_entry)); /* The record has shrunk a bit */ dbuf.dsize -= del_count * sizeof(share_mode_entry); if (tdb_store(tdb, locking_key(dev, inode), dbuf, TDB_REPLACE) == -1) { SAFE_FREE(shares); SAFE_FREE(dbuf.dptr); return 0; } } } SAFE_FREE(dbuf.dptr); *pp_shares = shares; return num_share_modes; }