Changeset 746 for vendor/current/source3/locking
- Timestamp:
- Nov 27, 2012, 4:56:06 PM (13 years ago)
- Location:
- vendor/current/source3/locking
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/locking/locking.c
r740 r746 45 45 #include "messages.h" 46 46 #include "util_tdb.h" 47 #include "../librpc/gen_ndr/ndr_security.h" 47 48 48 49 #undef DBGC_CLASS … … 552 553 553 554 for (i = 0; i < pdata->u.s.num_delete_token_entries; i++) { 554 uint32_t token_len; 555 DATA_BLOB blob; 556 enum ndr_err_code ndr_err; 555 557 struct delete_token_list *pdtl; 556 557 if (end_ptr - p < (sizeof(uint32_t) + sizeof(uint32_t) + 558 sizeof(uid_t) + sizeof(gid_t))) { 559 DEBUG(0,("parse_delete_tokens_list: " 560 "corrupt token list (%u)", 561 (unsigned int)(end_ptr - p))); 562 smb_panic("corrupt token list"); 563 return -1; 564 } 565 566 memcpy(&token_len, p, sizeof(token_len)); 567 delete_tokens_size += token_len; 568 569 if (p + token_len > end_ptr || token_len < sizeof(token_len) + 570 sizeof(pdtl->name_hash) + 571 sizeof(uid_t) + 572 sizeof(gid_t)) { 573 DEBUG(0,("parse_delete_tokens_list: " 574 "invalid token length (%u)\n", 575 (unsigned int)token_len )); 576 smb_panic("invalid token length"); 577 return -1; 578 } 579 580 p += sizeof(token_len); 558 size_t token_len = 0; 581 559 582 560 pdtl = TALLOC_ZERO_P(lck, struct delete_token_list); … … 588 566 memcpy(&pdtl->name_hash, p, sizeof(pdtl->name_hash)); 589 567 p += sizeof(pdtl->name_hash); 568 delete_tokens_size += sizeof(pdtl->name_hash); 590 569 591 570 pdtl->delete_token = TALLOC_ZERO_P(pdtl, struct security_unix_token); … … 595 574 } 596 575 597 /* Copy out the uid and gid. */ 598 memcpy(&pdtl->delete_token->uid, p, sizeof(uid_t)); 599 p += sizeof(uid_t); 600 memcpy(&pdtl->delete_token->gid, p, sizeof(gid_t)); 601 p += sizeof(gid_t); 602 603 token_len -= (sizeof(token_len) + sizeof(pdtl->name_hash) + 604 sizeof(uid_t) + sizeof(gid_t)); 605 606 /* Any supplementary groups ? */ 607 if (token_len) { 608 int j; 609 610 if (token_len % sizeof(gid_t) != 0) { 611 DEBUG(0,("parse_delete_tokens_list: " 612 "corrupt group list (%u)", 613 (unsigned int)(token_len % sizeof(gid_t)) )); 614 smb_panic("corrupt group list"); 615 return -1; 616 } 617 618 pdtl->delete_token->ngroups = token_len / sizeof(gid_t); 619 pdtl->delete_token->groups = TALLOC_ARRAY(pdtl->delete_token, gid_t, 620 pdtl->delete_token->ngroups); 621 if (pdtl->delete_token->groups == NULL) { 622 DEBUG(0,("parse_delete_tokens_list: talloc failed")); 623 return -1; 624 } 625 626 for (j = 0; j < pdtl->delete_token->ngroups; j++) { 627 memcpy(&pdtl->delete_token->groups[j], p, sizeof(gid_t)); 628 p += sizeof(gid_t); 629 } 630 } 576 if (p >= end_ptr) { 577 DEBUG(0,("parse_delete_tokens_list: corrupt data")); 578 return -1; 579 } 580 581 blob.data = p; 582 blob.length = end_ptr - p; 583 584 ndr_err = ndr_pull_struct_blob(&blob, 585 pdtl, 586 pdtl->delete_token, 587 (ndr_pull_flags_fn_t)ndr_pull_security_unix_token); 588 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 589 DEBUG(1, ("parse_delete_tokens_list: " 590 "ndr_pull_security_unix_token failed\n")); 591 return -1; 592 } 593 594 token_len = ndr_size_security_unix_token(pdtl->delete_token, 0); 595 596 p += token_len; 597 delete_tokens_size += token_len; 598 599 if (p >= end_ptr) { 600 DEBUG(0,("parse_delete_tokens_list: corrupt data")); 601 return -1; 602 } 603 604 pdtl->delete_nt_token = TALLOC_ZERO_P(pdtl, struct security_token); 605 if (pdtl->delete_nt_token == NULL) { 606 DEBUG(0,("parse_delete_tokens_list: talloc failed")); 607 return -1; 608 } 609 610 blob.data = p; 611 blob.length = end_ptr - p; 612 613 ndr_err = ndr_pull_struct_blob(&blob, 614 pdtl, 615 pdtl->delete_nt_token, 616 (ndr_pull_flags_fn_t)ndr_pull_security_token); 617 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 618 DEBUG(1, ("parse_delete_tokens_list: " 619 "ndr_pull_security_token failed\n")); 620 return -1; 621 } 622 623 token_len = ndr_size_security_token(pdtl->delete_nt_token, 0); 624 625 p += token_len; 626 delete_tokens_size += token_len; 627 631 628 /* Add to the list. */ 632 629 DLIST_ADD(lck->delete_tokens, pdtl); … … 770 767 for (pdtl = lck->delete_tokens; pdtl; pdtl = pdtl->next) { 771 768 num_delete_token_entries++; 772 delete_tokens_size += (sizeof(uint32_t) + 773 sizeof(uint32_t) + 774 sizeof(uid_t) + 775 sizeof(gid_t) + 776 pdtl->delete_token->ngroups*sizeof(gid_t)); 769 delete_tokens_size += sizeof(uint32_t) + 770 ndr_size_security_unix_token(pdtl->delete_token, 0) + 771 ndr_size_security_token(pdtl->delete_nt_token, 0); 777 772 } 778 773 … … 814 809 for (pdtl = lck->delete_tokens; pdtl; pdtl = pdtl->next) { 815 810 struct security_unix_token *pdt = pdtl->delete_token; 816 uint32_t token_size = sizeof(uint32_t) + 817 sizeof(uint32_t) + 818 sizeof(uid_t) + 819 sizeof(gid_t) + 820 (pdt->ngroups * sizeof(gid_t)); 811 struct security_token *pdt_nt = pdtl->delete_nt_token; 821 812 uint8_t *p = result.dptr + offset; 822 823 memcpy(p, &token_size, sizeof(uint32_t)); 824 p += sizeof(uint32_t); 813 DATA_BLOB blob; 814 enum ndr_err_code ndr_err; 825 815 826 816 memcpy(p, &pdtl->name_hash, sizeof(uint32_t)); 827 817 p += sizeof(uint32_t); 828 829 memcpy(p, &pdt->uid, sizeof(uid_t)); 830 p += sizeof(uid_t); 831 832 memcpy(p, &pdt->gid, sizeof(gid_t)); 833 p += sizeof(gid_t); 834 835 for (i = 0; i < pdt->ngroups; i++) { 836 memcpy(p, &pdt->groups[i], sizeof(gid_t)); 837 p += sizeof(gid_t); 838 } 839 offset += token_size; 818 offset += sizeof(uint32_t); 819 820 ndr_err = ndr_push_struct_blob(&blob, 821 talloc_tos(), 822 pdt, 823 (ndr_push_flags_fn_t)ndr_push_security_unix_token); 824 825 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 826 smb_panic("ndr_push_security_unix_token failed"); 827 } 828 829 /* We know we have space here as we counted above. */ 830 memcpy(p, blob.data, blob.length); 831 p += blob.length; 832 offset += blob.length; 833 TALLOC_FREE(blob.data); 834 835 ndr_err = ndr_push_struct_blob(&blob, 836 talloc_tos(), 837 pdt_nt, 838 (ndr_push_flags_fn_t)ndr_push_security_token); 839 840 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 841 smb_panic("ndr_push_security_token failed"); 842 } 843 844 /* We know we have space here as we counted above. */ 845 memcpy(p, blob.data, blob.length); 846 p += blob.length; 847 offset += blob.length; 848 TALLOC_FREE(blob.data); 840 849 } 841 850 … … 1460 1469 if (fsp->is_directory) { 1461 1470 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name)); 1471 1472 /* Or the root of a share. */ 1473 if (ISDOT(fsp->fsp_name->base_name)) { 1474 DEBUG(10,("can_set_delete_on_close: can't set delete on " 1475 "close for the root of a share.\n")); 1476 return NT_STATUS_ACCESS_DENIED; 1477 } 1478 1462 1479 return can_delete_directory(fsp->conn, 1463 1480 fsp->fsp_name->base_name); … … 1501 1518 static bool add_delete_on_close_token(struct share_mode_lock *lck, 1502 1519 uint32_t name_hash, 1520 const struct security_token *nt_tok, 1503 1521 const struct security_unix_token *tok) 1504 1522 { … … 1511 1529 1512 1530 dtl->name_hash = name_hash; 1513 dtl->delete_token = copy_unix_token( lck, tok);1531 dtl->delete_token = copy_unix_token(dtl, tok); 1514 1532 if (dtl->delete_token == NULL) { 1533 TALLOC_FREE(dtl); 1534 return false; 1535 } 1536 dtl->delete_nt_token = dup_nt_token(dtl, nt_tok); 1537 if (dtl->delete_nt_token == NULL) { 1515 1538 TALLOC_FREE(dtl); 1516 1539 return false; … … 1535 1558 struct share_mode_lock *lck, 1536 1559 bool delete_on_close, 1560 const struct security_token *nt_tok, 1537 1561 const struct security_unix_token *tok) 1538 1562 { … … 1541 1565 1542 1566 if (delete_on_close) { 1567 SMB_ASSERT(nt_tok != NULL); 1543 1568 SMB_ASSERT(tok != NULL); 1544 1569 } else { 1570 SMB_ASSERT(nt_tok == NULL); 1545 1571 SMB_ASSERT(tok == NULL); 1546 1572 } … … 1553 1579 DLIST_REMOVE(lck->delete_tokens, dtl); 1554 1580 TALLOC_FREE(dtl); 1555 return; 1581 } else { 1582 /* Replace this token with the 1583 given tok. */ 1584 TALLOC_FREE(dtl->delete_token); 1585 dtl->delete_token = copy_unix_token(dtl, tok); 1586 SMB_ASSERT(dtl->delete_token != NULL); 1587 TALLOC_FREE(dtl->delete_nt_token); 1588 dtl->delete_nt_token = dup_nt_token(dtl, nt_tok); 1589 SMB_ASSERT(dtl->delete_nt_token != NULL); 1556 1590 } 1557 /* Replace this token with the 1558 given tok. */ 1559 TALLOC_FREE(dtl->delete_token); 1560 dtl->delete_token = copy_unix_token(dtl, tok); 1561 SMB_ASSERT(dtl->delete_token != NULL); 1591 return; 1562 1592 } 1563 1593 } … … 1568 1598 } 1569 1599 1570 ret = add_delete_on_close_token(lck, fsp->name_hash, tok);1600 ret = add_delete_on_close_token(lck, fsp->name_hash, nt_tok, tok); 1571 1601 SMB_ASSERT(ret); 1572 1602 } 1573 1603 1574 bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const struct security_unix_token *tok) 1604 bool set_delete_on_close(files_struct *fsp, bool delete_on_close, 1605 const struct security_token *nt_tok, 1606 const struct security_unix_token *tok) 1575 1607 { 1576 1608 struct share_mode_lock *lck; … … 1587 1619 } 1588 1620 1589 set_delete_on_close_lck(fsp, lck, delete_on_close, 1590 delete_on_close ? tok : NULL); 1621 if (delete_on_close) { 1622 set_delete_on_close_lck(fsp, lck, true, 1623 nt_tok, 1624 tok); 1625 } else { 1626 set_delete_on_close_lck(fsp, lck, false, 1627 NULL, 1628 NULL); 1629 } 1591 1630 1592 1631 if (fsp->is_directory) { … … 1603 1642 } 1604 1643 1605 const struct security_unix_token *get_delete_on_close_token(struct share_mode_lock *lck, uint32_t name_hash) 1644 /**************************************************************************** 1645 Return the NT token and UNIX token if there's a match. Return true if 1646 found, false if not. 1647 ****************************************************************************/ 1648 1649 bool get_delete_on_close_token(struct share_mode_lock *lck, 1650 uint32_t name_hash, 1651 const struct security_token **pp_nt_tok, 1652 const struct security_unix_token **pp_tok) 1606 1653 { 1607 1654 struct delete_token_list *dtl; … … 1614 1661 (unsigned int)dtl->name_hash )); 1615 1662 if (dtl->name_hash == name_hash) { 1616 return dtl->delete_token; 1617 } 1618 } 1619 return NULL; 1663 if (pp_nt_tok) { 1664 *pp_nt_tok = dtl->delete_nt_token; 1665 } 1666 if (pp_tok) { 1667 *pp_tok = dtl->delete_token; 1668 } 1669 return true; 1670 } 1671 } 1672 return false; 1620 1673 } 1621 1674 1622 1675 bool is_delete_on_close_set(struct share_mode_lock *lck, uint32_t name_hash) 1623 1676 { 1624 return (get_delete_on_close_token(lck, name_hash) !=NULL);1677 return get_delete_on_close_token(lck, name_hash, NULL, NULL); 1625 1678 } 1626 1679 … … 1683 1736 { 1684 1737 struct forall_state *state = (struct forall_state *)_state; 1685 struct locking_data *data;1686 struct share_mode_entry *shares;1687 const char *sharepath;1688 const char *fname;1689 const char *del_tokens;1690 uint32_t total_del_token_size = 0;1691 1738 int i; 1739 struct share_mode_lock *lck; 1692 1740 1693 1741 /* Ensure this is a locking_key record. */ … … 1695 1743 return 0; 1696 1744 1697 data = (struct locking_data *)rec->value.dptr; 1698 shares = (struct share_mode_entry *)(rec->value.dptr + sizeof(*data)); 1699 del_tokens = (const char *)rec->value.dptr + sizeof(*data) + 1700 data->u.s.num_share_mode_entries*sizeof(*shares); 1701 1702 for (i = 0; i < data->u.s.num_delete_token_entries; i++) { 1703 uint32_t del_token_size; 1704 memcpy(&del_token_size, del_tokens, sizeof(uint32_t)); 1705 total_del_token_size += del_token_size; 1706 del_tokens += del_token_size; 1707 } 1708 1709 sharepath = (const char *)rec->value.dptr + sizeof(*data) + 1710 data->u.s.num_share_mode_entries*sizeof(*shares) + 1711 total_del_token_size; 1712 fname = (const char *)rec->value.dptr + sizeof(*data) + 1713 data->u.s.num_share_mode_entries*sizeof(*shares) + 1714 total_del_token_size + 1715 strlen(sharepath) + 1; 1716 1717 for (i=0;i<data->u.s.num_share_mode_entries;i++) { 1718 state->fn(&shares[i], sharepath, fname, 1719 state->private_data); 1720 } 1745 lck = TALLOC_ZERO_P(talloc_tos(), struct share_mode_lock); 1746 if (lck == NULL) { 1747 return 0; 1748 } 1749 1750 if (!parse_share_modes(rec->value, lck)) { 1751 TALLOC_FREE(lck); 1752 DEBUG(1, ("parse_share_modes failed\n")); 1753 return 0; 1754 } 1755 1756 for (i=0; i<lck->num_share_modes; i++) { 1757 struct share_mode_entry *se = &lck->share_modes[i]; 1758 state->fn(se, 1759 lck->servicepath, 1760 lck->base_name, 1761 state->private_data); 1762 } 1763 TALLOC_FREE(lck); 1721 1764 return 0; 1722 1765 } -
vendor/current/source3/locking/proto.h
r740 r746 174 174 bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp); 175 175 NTSTATUS can_set_delete_on_close(files_struct *fsp, uint32 dosmode); 176 const struct security_unix_token *get_delete_on_close_token(struct share_mode_lock *lck, uint32_t name_hash); 176 bool get_delete_on_close_token(struct share_mode_lock *lck, 177 uint32_t name_hash, 178 const struct security_token **pp_nt_tok, 179 const struct security_unix_token **pp_tok); 177 180 void set_delete_on_close_lck(files_struct *fsp, 178 181 struct share_mode_lock *lck, 179 182 bool delete_on_close, 183 const struct security_token *nt_tok, 180 184 const struct security_unix_token *tok); 181 bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const struct security_unix_token *tok); 185 bool set_delete_on_close(files_struct *fsp, bool delete_on_close, 186 const struct security_token *nt_tok, 187 const struct security_unix_token *tok); 182 188 bool is_delete_on_close_set(struct share_mode_lock *lck, uint32_t name_hash); 183 189 bool set_sticky_write_time(struct file_id fileid, struct timespec write_time);
Note:
See TracChangeset
for help on using the changeset viewer.