+static int parse_delete_tokens_list(struct share_mode_lock *lck,
+ struct locking_data *pdata,
+ const TDB_DATA dbuf)
+{
+ uint8_t *p = dbuf.dptr + sizeof(struct locking_data) +
+ (lck->num_share_modes *
+ sizeof(struct share_mode_entry));
+ uint8_t *end_ptr = dbuf.dptr + (dbuf.dsize - 2);
+ int delete_tokens_size = 0;
+ int i;
+
+ lck->delete_tokens = NULL;
+
+ for (i = 0; i < pdata->u.s.num_delete_token_entries; i++) {
+ uint32_t token_len;
+ struct delete_token_list *pdtl;
+
+ if (end_ptr - p < (sizeof(uint32_t) + sizeof(uint32_t) +
+ sizeof(uid_t) + sizeof(gid_t))) {
+ DEBUG(0,("parse_delete_tokens_list: "
+ "corrupt token list (%u)",
+ (unsigned int)(end_ptr - p)));
+ smb_panic("corrupt token list");
+ return -1;
+ }
+
+ memcpy(&token_len, p, sizeof(token_len));
+ delete_tokens_size += token_len;
+
+ if (p + token_len > end_ptr || token_len < sizeof(token_len) +
+ sizeof(pdtl->name_hash) +
+ sizeof(uid_t) +
+ sizeof(gid_t)) {
+ DEBUG(0,("parse_delete_tokens_list: "
+ "invalid token length (%u)\n",
+ (unsigned int)token_len ));
+ smb_panic("invalid token length");
+ return -1;
+ }
+
+ p += sizeof(token_len);
+
+ pdtl = TALLOC_ZERO_P(lck, struct delete_token_list);
+ if (pdtl == NULL) {
+ DEBUG(0,("parse_delete_tokens_list: talloc failed"));
+ return -1;
+ }
+ /* Copy out the name_hash. */
+ memcpy(&pdtl->name_hash, p, sizeof(pdtl->name_hash));
+ p += sizeof(pdtl->name_hash);
+
+ pdtl->delete_token = TALLOC_ZERO_P(pdtl, struct security_unix_token);
+ if (pdtl->delete_token == NULL) {
+ DEBUG(0,("parse_delete_tokens_list: talloc failed"));
+ return -1;
+ }
+
+ /* Copy out the uid and gid. */
+ memcpy(&pdtl->delete_token->uid, p, sizeof(uid_t));
+ p += sizeof(uid_t);
+ memcpy(&pdtl->delete_token->gid, p, sizeof(gid_t));
+ p += sizeof(gid_t);
+
+ token_len -= (sizeof(token_len) + sizeof(pdtl->name_hash) +
+ sizeof(uid_t) + sizeof(gid_t));
+
+ /* Any supplementary groups ? */
+ if (token_len) {
+ int j;
+
+ if (token_len % sizeof(gid_t) != 0) {
+ DEBUG(0,("parse_delete_tokens_list: "
+ "corrupt group list (%u)",
+ (unsigned int)(token_len % sizeof(gid_t)) ));
+ smb_panic("corrupt group list");
+ return -1;
+ }
+
+ pdtl->delete_token->ngroups = token_len / sizeof(gid_t);
+ pdtl->delete_token->groups = talloc_array(pdtl->delete_token, gid_t,
+ pdtl->delete_token->ngroups);
+ if (pdtl->delete_token->groups == NULL) {
+ DEBUG(0,("parse_delete_tokens_list: talloc failed"));
+ return -1;
+ }
+
+ for (j = 0; j < pdtl->delete_token->ngroups; j++) {
+ memcpy(&pdtl->delete_token->groups[j], p, sizeof(gid_t));
+ p += sizeof(gid_t);
+ }
+ }
+ /* Add to the list. */
+ DLIST_ADD(lck->delete_tokens, pdtl);
+ }
+
+ return delete_tokens_size;
+}
+