7
7
Copyright (C) Tom Jansen (Ninja ISD) 2002
8
8
Copyright (C) Derrell Lipman 2003-2008
9
9
Copyright (C) Jeremy Allison 2007, 2008
11
11
This program is free software; you can redistribute it and/or modify
12
12
it under the terms of the GNU General Public License as published by
13
13
the Free Software Foundation; either version 3 of the License, or
14
14
(at your option) any later version.
16
16
This program is distributed in the hope that it will be useful,
17
17
but WITHOUT ANY WARRANTY; without even the implied warranty of
18
18
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
19
GNU General Public License for more details.
21
21
You should have received a copy of the GNU General Public License
22
22
along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
#include "includes.h"
26
#include "libsmb/libsmb.h"
26
27
#include "libsmbclient.h"
27
28
#include "libsmb_internal.h"
29
#include "../librpc/gen_ndr/ndr_lsa.h"
30
#include "rpc_client/rpc_client.h"
31
#include "rpc_client/cli_lsarpc.h"
32
#include "../libcli/security/security.h"
31
35
* Find an lsa pipe handle associated with a cli struct.
34
38
find_lsa_pipe_hnd(struct cli_state *ipc_cli)
36
40
struct rpc_pipe_client *pipe_hnd;
38
42
for (pipe_hnd = ipc_cli->pipe_list;
40
44
pipe_hnd = pipe_hnd->next) {
42
45
if (ndr_syntax_id_equal(&pipe_hnd->abstract_syntax,
43
46
&ndr_table_lsarpc.syntax_id)) {
58
ace_compare(SEC_ACE *ace1,
60
ace_compare(struct security_ace *ace1,
61
struct security_ace *ace2)
64
66
/* If the ACEs are equal, we have nothing more to do. */
65
67
if (sec_ace_equal(ace1, ace2)) {
69
71
/* Inherited follow non-inherited */
70
72
b1 = ((ace1->flags & SEC_ACE_FLAG_INHERITED_ACE) != 0);
71
73
b2 = ((ace2->flags & SEC_ACE_FLAG_INHERITED_ACE) != 0);
73
75
return (b1 ? 1 : -1);
77
79
* What shall we do with AUDITs and ALARMs? It's undefined. We'll
78
80
* sort them after DENY and ALLOW.
110
112
return (b1 ? 1 : -1);
114
116
* If we get this far, the ACEs are similar as far as the
115
117
* characteristics we typically care about (those defined by the
116
118
* referenced MS document). We'll now sort by characteristics that
117
119
* just seems reasonable.
120
122
if (ace1->type != ace2->type) {
121
123
return ace2->type - ace1->type;
124
if (sid_compare(&ace1->trustee, &ace2->trustee)) {
125
return sid_compare(&ace1->trustee, &ace2->trustee);
126
if (dom_sid_compare(&ace1->trustee, &ace2->trustee)) {
127
return dom_sid_compare(&ace1->trustee, &ace2->trustee);
128
130
if (ace1->flags != ace2->flags) {
129
131
return ace1->flags - ace2->flags;
132
134
if (ace1->access_mask != ace2->access_mask) {
133
135
return ace1->access_mask - ace2->access_mask;
136
138
if (ace1->size != ace2->size) {
137
139
return ace1->size - ace2->size;
140
return memcmp(ace1, ace2, sizeof(SEC_ACE));
142
return memcmp(ace1, ace2, sizeof(struct security_ace));
145
sort_acl(SEC_ACL *the_acl)
147
sort_acl(struct security_acl *the_acl)
148
150
if (!the_acl) return;
150
qsort(the_acl->aces, the_acl->num_aces, sizeof(the_acl->aces[0]),
151
QSORT_CAST ace_compare);
152
TYPESAFE_QSORT(the_acl->aces, the_acl->num_aces, ace_compare);
153
154
for (i=1;i<the_acl->num_aces;) {
154
155
if (sec_ace_equal(&the_acl->aces[i-1], &the_acl->aces[i])) {
169
170
struct policy_handle *pol,
174
175
char **domains = NULL;
175
176
char **names = NULL;
176
177
enum lsa_SidType *types = NULL;
177
178
struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli);
180
181
sid_to_fstring(str, sid);
183
184
return; /* no lookup desired */
190
191
/* Ask LSA to convert the sid to a name */
192
193
ctx = talloc_stackframe();
194
195
if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_sids(pipe_hnd, ctx,
195
196
pol, 1, sid, &domains,
196
197
&names, &types)) ||
213
214
convert_string_to_sid(struct cli_state *ipc_cli,
214
215
struct policy_handle *pol,
219
220
enum lsa_SidType *types = NULL;
220
DOM_SID *sids = NULL;
221
struct dom_sid *sids = NULL;
221
222
bool result = True;
222
223
TALLOC_CTX *ctx = NULL;
223
224
struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli);
230
231
if (strncmp(str, "S-", 2) == 0) {
231
232
return string_to_sid(sid, str);
238
239
ctx = talloc_stackframe();
239
240
if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_names(pipe_hnd, ctx,
247
248
sid_copy(sid, &sids[0]);
250
250
TALLOC_FREE(ctx);
255
/* parse an ACE in the same format as print_ace() */
255
/* parse an struct security_ace in the same format as print_ace() */
257
257
parse_ace(struct cli_state *ipc_cli,
258
258
struct policy_handle *pol,
259
struct security_ace *ace,
305
304
/* Try to parse numeric form */
307
306
if (sscanf(p, "%i/%i/%i", &atype, &aflags, &amask) == 3 &&
308
307
convert_string_to_sid(ipc_cli, pol, numeric, &sid, str)) {
312
311
/* Try to parse text form */
314
313
if (!convert_string_to_sid(ipc_cli, pol, numeric, &sid, str)) {
315
314
TALLOC_FREE(frame);
320
319
if (!next_token_talloc(frame, &cp, &tok, "/")) {
321
320
TALLOC_FREE(frame);
325
324
if (StrnCaseCmp(tok, "ALLOWED", strlen("ALLOWED")) == 0) {
326
325
atype = SEC_ACE_TYPE_ACCESS_ALLOWED;
327
326
} else if (StrnCaseCmp(tok, "DENIED", strlen("DENIED")) == 0) {
330
329
TALLOC_FREE(frame);
334
333
/* Only numeric form accepted for flags at present */
336
335
if (!(next_token_talloc(frame, &cp, &tok, "/") &&
337
336
sscanf(tok, "%i", &aflags))) {
338
337
TALLOC_FREE(frame);
342
341
if (!next_token_talloc(frame, &cp, &tok, "/")) {
343
342
TALLOC_FREE(frame);
347
346
if (strncmp(tok, "0x", 2) == 0) {
348
347
if (sscanf(tok, "%i", &amask) != 1) {
349
348
TALLOC_FREE(frame);
355
354
for (v = standard_values; v->perm; v++) {
356
355
if (strcmp(tok, v->perm) == 0) {
365
364
bool found = False;
367
366
for (v = special_values; v->perm; v++) {
368
367
if (v->perm[0] == *p) {
369
368
amask |= v->mask;
375
374
TALLOC_FREE(frame);
382
381
TALLOC_FREE(frame);
388
387
init_sec_ace(ace, &sid, atype, mask, aflags);
393
/* add an ACE to a list of ACEs in a SEC_ACL */
392
/* add an struct security_ace to a list of struct security_aces in a struct security_acl */
395
add_ace(SEC_ACL **the_acl,
394
add_ace(struct security_acl **the_acl,
395
struct security_ace *ace,
398
struct security_acl *newacl;
399
struct security_ace *aces;
402
401
if (! *the_acl) {
403
402
(*the_acl) = make_sec_acl(ctx, 3, 1, ace);
407
if ((aces = SMB_CALLOC_ARRAY(SEC_ACE,
406
if ((aces = SMB_CALLOC_ARRAY(struct security_ace,
408
407
1+(*the_acl)->num_aces)) == NULL) {
411
memcpy(aces, (*the_acl)->aces, (*the_acl)->num_aces * sizeof(SEC_ACE));
412
memcpy(aces+(*the_acl)->num_aces, ace, sizeof(SEC_ACE));
410
memcpy(aces, (*the_acl)->aces, (*the_acl)->num_aces * sizeof(struct security_ace));
411
memcpy(aces+(*the_acl)->num_aces, ace, sizeof(struct security_ace));
413
412
newacl = make_sec_acl(ctx, (*the_acl)->revision,
414
413
1+(*the_acl)->num_aces, aces);
421
420
/* parse a ascii version of a security descriptor */
421
static struct security_descriptor *
423
422
sec_desc_parse(TALLOC_CTX *ctx,
424
423
struct cli_state *ipc_cli,
425
424
struct policy_handle *pol,
429
428
const char *p = str;
431
SEC_DESC *ret = NULL;
430
struct security_descriptor *ret = NULL;
433
DOM_SID *group_sid=NULL;
434
DOM_SID *owner_sid=NULL;
432
struct dom_sid *group_sid=NULL;
433
struct dom_sid *owner_sid=NULL;
434
struct security_acl *dacl=NULL;
438
437
while (next_token_talloc(ctx, &p, &tok, "\t,\r\n")) {
440
439
if (StrnCaseCmp(tok,"REVISION:", 9) == 0) {
441
440
revision = strtol(tok+9, NULL, 16);
445
444
if (StrnCaseCmp(tok,"OWNER:", 6) == 0) {
447
446
DEBUG(5,("OWNER specified more than once!\n"));
450
owner_sid = SMB_CALLOC_ARRAY(DOM_SID, 1);
449
owner_sid = SMB_CALLOC_ARRAY(struct dom_sid, 1);
451
450
if (!owner_sid ||
452
451
!convert_string_to_sid(ipc_cli, pol,
461
460
if (StrnCaseCmp(tok,"OWNER+:", 7) == 0) {
463
462
DEBUG(5,("OWNER specified more than once!\n"));
466
owner_sid = SMB_CALLOC_ARRAY(DOM_SID, 1);
465
owner_sid = SMB_CALLOC_ARRAY(struct dom_sid, 1);
467
466
if (!owner_sid ||
468
467
!convert_string_to_sid(ipc_cli, pol,
477
476
if (StrnCaseCmp(tok,"GROUP:", 6) == 0) {
479
478
DEBUG(5,("GROUP specified more than once!\n"));
482
group_sid = SMB_CALLOC_ARRAY(DOM_SID, 1);
481
group_sid = SMB_CALLOC_ARRAY(struct dom_sid, 1);
483
482
if (!group_sid ||
484
483
!convert_string_to_sid(ipc_cli, pol,
493
492
if (StrnCaseCmp(tok,"GROUP+:", 7) == 0) {
495
494
DEBUG(5,("GROUP specified more than once!\n"));
498
group_sid = SMB_CALLOC_ARRAY(DOM_SID, 1);
497
group_sid = SMB_CALLOC_ARRAY(struct dom_sid, 1);
499
498
if (!group_sid ||
500
499
!convert_string_to_sid(ipc_cli, pol,
509
508
if (StrnCaseCmp(tok,"ACL:", 4) == 0) {
509
struct security_ace ace;
511
510
if (!parse_ace(ipc_cli, pol, &ace, numeric, tok+4)) {
512
511
DEBUG(5, ("Failed to parse ACL %s\n", tok));
522
521
if (StrnCaseCmp(tok,"ACL+:", 5) == 0) {
522
struct security_ace ace;
524
523
if (!parse_ace(ipc_cli, pol, &ace, False, tok+5)) {
525
524
DEBUG(5, ("Failed to parse ACL %s\n", tok));
535
534
DEBUG(5, ("Failed to parse security descriptor\n"));
539
538
ret = make_sec_desc(ctx, revision, SEC_DESC_SELF_RELATIVE,
540
539
owner_sid, group_sid, NULL, dacl, &sd_size);
543
542
SAFE_FREE(group_sid);
544
543
SAFE_FREE(owner_sid);
563
561
SMB_INO_T inode = 0;
564
562
DOS_ATTR_DESC *ret;
566
564
ret = TALLOC_P(ctx, DOS_ATTR_DESC);
572
570
/* Obtain the DOS attributes */
573
571
if (!SMBC_getatr(context, srv, CONST_DISCARD(char *, filename),
640
638
frame = talloc_stackframe();
641
639
while (next_token_talloc(frame, &p, &tok, "\t,\r\n")) {
642
640
if (StrnCaseCmp(tok, "MODE:", 5) == 0) {
655
653
if (StrnCaseCmp(tok, "SIZE:", 5) == 0) {
656
654
dad->size = (SMB_OFF_T)atof(tok+5);
660
658
n = strlen(attr_strings.access_time_attr);
661
659
if (StrnCaseCmp(tok, attr_strings.access_time_attr, n) == 0) {
662
660
dad->access_time = (time_t)strtol(tok+n+1, NULL, 10);
666
664
n = strlen(attr_strings.change_time_attr);
667
665
if (StrnCaseCmp(tok, attr_strings.change_time_attr, n) == 0) {
668
666
dad->change_time = (time_t)strtol(tok+n+1, NULL, 10);
672
670
n = strlen(attr_strings.write_time_attr);
673
671
if (StrnCaseCmp(tok, attr_strings.write_time_attr, n) == 0) {
674
672
dad->write_time = (time_t)strtol(tok+n+1, NULL, 10);
678
676
if (attr_strings.create_time_attr != NULL) {
679
677
n = strlen(attr_strings.create_time_attr);
680
678
if (StrnCaseCmp(tok, attr_strings.create_time_attr,
769
767
attr_strings.access_time_attr = "ACCESS_TIME";
770
768
attr_strings.write_time_attr = "WRITE_TIME";
771
769
attr_strings.change_time_attr = "CHANGE_TIME";
773
771
excl_attr_strings.create_time_attr = "CREATE_TIME";
774
772
excl_attr_strings.access_time_attr = "ACCESS_TIME";
775
773
excl_attr_strings.write_time_attr = "WRITE_TIME";
780
778
attr_strings.access_time_attr = "A_TIME";
781
779
attr_strings.write_time_attr = "M_TIME";
782
780
attr_strings.change_time_attr = "C_TIME";
784
782
excl_attr_strings.create_time_attr = NULL;
785
783
excl_attr_strings.access_time_attr = "dos_attr.A_TIME";
786
784
excl_attr_strings.write_time_attr = "dos_attr.M_TIME";
787
785
excl_attr_strings.change_time_attr = "dos_attr.C_TIME";
790
788
/* Copy name so we can strip off exclusions (if any are specified) */
791
789
strncpy(name_sandbox, attr_name, sizeof(name_sandbox) - 1);
793
791
/* Ensure name is null terminated */
794
792
name_sandbox[sizeof(name_sandbox) - 1] = '\0';
796
794
/* Play in the sandbox */
797
795
name = name_sandbox;
799
797
/* If there are any exclusions, point to them and mask them from name */
800
798
if ((pExclude = strchr(name, '!')) != NULL)
802
800
*pExclude++ = '\0';
805
803
all = (StrnCaseCmp(name, "system.*", 8) == 0);
806
804
all_nt = (StrnCaseCmp(name, "system.nt_sec_desc.*", 20) == 0);
807
805
all_nt_acls = (StrnCaseCmp(name, "system.nt_sec_desc.acl.*", 24) == 0);
809
807
some_nt = (StrnCaseCmp(name, "system.nt_sec_desc.", 19) == 0);
810
808
some_dos = (StrnCaseCmp(name, "system.dos_attr.", 16) == 0);
811
809
numeric = (* (name + strlen(name) - 1) != '+');
813
811
/* Look for exclusions from "all" requests */
814
812
if (all || all_nt || all_dos) {
816
813
/* Exclusions are delimited by '!' */
818
815
pExclude != NULL;
819
816
pExclude = (p == NULL ? NULL : p + 1)) {
821
818
/* Find end of this exclusion name */
822
819
if ((p = strchr(pExclude, '!')) != NULL)
827
824
/* Which exclusion name is this? */
828
825
if (StrCaseCmp(pExclude,
829
826
"nt_sec_desc.revision") == 0) {
1058
1055
if (! exclude_nt_acl) {
1059
1056
/* Add aces to value buffer */
1060
1057
for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
1062
SEC_ACE *ace = &sd->dacl->aces[i];
1059
struct security_ace *ace = &sd->dacl->aces[i];
1063
1060
convert_sid_to_string(ipc_cli, pol,
1064
1061
sidstr, numeric,
1065
1062
&ace->trustee);
1067
1064
if (all || all_nt) {
1068
1065
if (determine_size) {
1069
1066
p = talloc_asprintf(
1150
1147
/* Restore name pointer to its original value */
1154
1151
if (all || some_dos) {
1155
1152
/* Point to the portion after "system.dos_attr." */
1156
1153
name += 16; /* if (all) this will be invalid but unused */
1158
1155
/* Obtain the DOS attributes */
1159
1156
if (!SMBC_getatr(context, srv, filename, &mode, &size,
1160
1157
&create_time_ts,
1162
1159
&write_time_ts,
1163
1160
&change_time_ts,
1166
1163
errno = SMBC_errno(context, srv->cli);
1171
1167
create_time = convert_timespec_to_time_t(create_time_ts);
1172
1168
access_time = convert_timespec_to_time_t(access_time_ts);
1173
1169
write_time = convert_timespec_to_time_t(write_time_ts);
1174
1170
change_time = convert_timespec_to_time_t(change_time_ts);
1176
1172
if (! exclude_dos_mode) {
1177
1173
if (all || all_dos) {
1178
1174
if (determine_size) {
1509
1505
uint16_t fnum = (uint16_t)-1;
1511
SEC_DESC *sd = NULL, *old;
1512
SEC_ACL *dacl = NULL;
1513
DOM_SID *owner_sid = NULL;
1514
DOM_SID *group_sid = NULL;
1507
struct security_descriptor *sd = NULL, *old;
1508
struct security_acl *dacl = NULL;
1509
struct dom_sid *owner_sid = NULL;
1510
struct dom_sid *group_sid = NULL;
1516
1512
size_t sd_size;
1519
1515
bool numeric = True;
1520
1516
char *targetpath = NULL;
1521
1517
struct cli_state *targetcli = NULL;
1523
1520
/* the_acl will be null for REMOVE_ALL operations */
1525
1522
numeric = ((p = strchr(the_acl, ':')) != NULL &&
1529
1526
/* if this is to set the entire ACL... */
1530
1527
if (*the_acl == '*') {
1531
1528
/* ... then increment past the first colon */
1532
1529
the_acl = p + 1;
1535
1532
sd = sec_desc_parse(ctx, ipc_cli, pol, numeric, the_acl);
1538
1534
errno = EINVAL;
1543
1539
/* SMBC_XATTR_MODE_REMOVE_ALL is the only caller
1544
1540
that doesn't deref sd */
1546
1542
if (!sd && (mode != SMBC_XATTR_MODE_REMOVE_ALL)) {
1547
1543
errno = EINVAL;
1613
1609
case SMBC_XATTR_MODE_ADD:
1614
1610
for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) {
1615
1611
bool found = False;
1617
1613
for (j=0;old->dacl && j<old->dacl->num_aces;j++) {
1618
if (sid_equal(&sd->dacl->aces[i].trustee,
1614
if (dom_sid_equal(&sd->dacl->aces[i].trustee,
1619
1615
&old->dacl->aces[j].trustee)) {
1620
1616
if (!(flags & SMBC_XATTR_FLAG_CREATE)) {
1631
1627
if (!found && (flags & SMBC_XATTR_FLAG_REPLACE)) {
1637
1633
for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) {
1638
1634
add_ace(&old->dacl, &sd->dacl->aces[i], ctx);
1641
1637
dacl = old->dacl;
1644
1640
case SMBC_XATTR_MODE_SET:
1646
1642
owner_sid = old->owner_sid;
1647
1643
group_sid = old->group_sid;
1648
1644
dacl = old->dacl;
1651
1647
case SMBC_XATTR_MODE_CHOWN:
1652
1648
owner_sid = sd->owner_sid;
1655
1651
case SMBC_XATTR_MODE_CHGRP:
1656
1652
group_sid = sd->group_sid;
1660
1656
/* Denied ACE entries must come before allowed ones */
1661
1657
sort_acl(old->dacl);
1663
1659
/* Create new security descriptor and set it */
1664
1660
sd = make_sec_desc(ctx, old->revision, SEC_DESC_SELF_RELATIVE,
1665
1661
owner_sid, group_sid, NULL, dacl, &sd_size);
1667
1663
if (!NT_STATUS_IS_OK(cli_ntcreate(targetcli, targetpath, 0,
1668
1664
WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS, 0,
1669
1665
FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0x0, 0x0, &fnum))) {
1676
if (!cli_set_secdesc(targetcli, fnum, sd)) {
1672
status = cli_set_secdesc(targetcli, fnum, sd);
1673
if (!NT_STATUS_IS_OK(status)) {
1677
1674
DEBUG(5, ("ERROR: secdesc set failed: %s\n",
1678
cli_errstr(targetcli)));
1675
nt_errstr(status)));
1685
1682
cli_close(targetcli, fnum);
1687
1684
if (err != 0) {
1718
1715
const char * change_time_attr;
1719
1716
} attr_strings;
1720
1717
TALLOC_CTX *frame = talloc_stackframe();
1722
1719
if (!context || !context->internal->initialized) {
1724
1720
errno = EINVAL; /* Best I can think of ... */
1725
1721
TALLOC_FREE(frame);
1730
1726
errno = EINVAL;
1731
1727
TALLOC_FREE(frame);
1735
1731
DEBUG(4, ("smbc_setxattr(%s, %s, %.*s)\n",
1736
1732
fname, name, (int) size, (const char*)value));
1738
1734
if (SMBC_parse_path(frame,
1762
1758
srv = SMBC_server(frame, context, True,
1763
1759
server, share, &workgroup, &user, &password);
1765
1761
TALLOC_FREE(frame);
1766
1762
return -1; /* errno set by SMBC_server */
1769
1765
if (! srv->no_nt_session) {
1770
1766
ipc_srv = SMBC_attr_server(frame, context, server, share,
1771
1767
&workgroup, &user, &password);
1791
1787
TALLOC_FREE(frame);
1796
1792
ret = cacl_set(context, talloc_tos(), srv->cli,
1797
1793
ipc_srv->cli, &ipc_srv->pol, path,
1807
1803
/* get a DOS Attribute Descriptor with current attributes */
1808
1804
dad = dos_attr_query(context, talloc_tos(), path, srv);
1810
1806
/* Overwrite old with new, using what was provided */
1811
1807
dos_attr_parse(context, dad, srv, namevalue);
1813
1809
/* Set the new DOS attributes */
1814
1810
if (! SMBC_setatr(context, srv, path,
1815
1811
dad->create_time,
1844
1840
StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 ||
1845
1841
StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 ||
1846
1842
StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) {
1849
1845
char *namevalue =
1850
1846
talloc_asprintf(talloc_tos(), "%s:%s",
1851
1847
name+19, (const char *) value);
1853
1849
if (! ipc_srv) {
1854
1850
ret = -1; /* errno set by SMBC_server() */
1868
1864
TALLOC_FREE(frame);
1873
1869
* Are they asking to set the owner?
1875
1871
if (StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 ||
1876
1872
StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0) {
1879
1875
char *namevalue =
1880
1876
talloc_asprintf(talloc_tos(), "%s:%s",
1881
1877
name+19, (const char *) value);
1883
1879
if (! ipc_srv) {
1884
1880
ret = -1; /* errno set by SMBC_server() */
1894
1890
TALLOC_FREE(frame);
1899
1895
* Are they asking to set the group?
1901
1897
if (StrCaseCmp(name, "system.nt_sec_desc.group") == 0 ||
1902
1898
StrCaseCmp(name, "system.nt_sec_desc.group+") == 0) {
1905
1901
char *namevalue =
1906
1902
talloc_asprintf(talloc_tos(), "%s:%s",
1907
1903
name+19, (const char *) value);
1909
1905
if (! ipc_srv) {
1910
1906
/* errno set by SMBC_server() */
1947
1943
StrCaseCmp(name, attr_strings.access_time_attr) == 0 ||
1948
1944
StrCaseCmp(name, attr_strings.write_time_attr) == 0 ||
1949
1945
StrCaseCmp(name, attr_strings.change_time_attr) == 0) {
1951
1947
/* get a DOS Attribute Descriptor with current attributes */
1952
1948
dad = dos_attr_query(context, talloc_tos(), path, srv);
1961
1957
/* Overwrite old with provided new params */
1962
1958
dos_attr_parse(context, dad, srv, namevalue);
1964
1960
/* Set the new DOS attributes */
1965
1961
ret2 = SMBC_setatr(context, srv, path,
1966
1962
dad->create_time,
2013
2009
const char * change_time_attr;
2014
2010
} attr_strings;
2015
2011
TALLOC_CTX *frame = talloc_stackframe();
2017
2013
if (!context || !context->internal->initialized) {
2019
2014
errno = EINVAL; /* Best I can think of ... */
2020
2015
TALLOC_FREE(frame);
2025
2020
errno = EINVAL;
2026
2021
TALLOC_FREE(frame);
2030
2025
DEBUG(4, ("smbc_getxattr(%s, %s)\n", fname, name));
2032
2027
if (SMBC_parse_path(frame,
2056
2051
srv = SMBC_server(frame, context, True,
2057
2052
server, share, &workgroup, &user, &password);
2059
2054
TALLOC_FREE(frame);
2060
2055
return -1; /* errno set by SMBC_server */
2063
2058
if (! srv->no_nt_session) {
2064
2059
ipc_srv = SMBC_attr_server(frame, context, server, share,
2065
2060
&workgroup, &user, &password);
2084
2079
attr_strings.write_time_attr = "system.dos_attr.M_TIME";
2085
2080
attr_strings.change_time_attr = "system.dos_attr.C_TIME";
2088
2083
/* Are they requesting a supported attribute? */
2089
2084
if (StrCaseCmp(name, "system.*") == 0 ||
2090
2085
StrnCaseCmp(name, "system.*!", 9) == 0 ||
2111
2106
StrCaseCmp(name, attr_strings.write_time_attr) == 0 ||
2112
2107
StrCaseCmp(name, attr_strings.change_time_attr) == 0 ||
2113
2108
StrCaseCmp(name, "system.dos_attr.inode") == 0) {
2116
2111
char *filename = (char *) name;
2117
2112
ret = cacl_get(context, talloc_tos(), srv,
2149
2144
char *workgroup = NULL;
2150
2145
char *path = NULL;
2151
2146
TALLOC_CTX *frame = talloc_stackframe();
2153
2148
if (!context || !context->internal->initialized) {
2155
2149
errno = EINVAL; /* Best I can think of ... */
2156
2150
TALLOC_FREE(frame);
2161
2155
errno = EINVAL;
2162
2156
TALLOC_FREE(frame);
2166
2160
DEBUG(4, ("smbc_removexattr(%s, %s)\n", fname, name));
2168
2162
if (SMBC_parse_path(frame,
2192
2186
srv = SMBC_server(frame, context, True,
2193
2187
server, share, &workgroup, &user, &password);
2195
2189
TALLOC_FREE(frame);
2196
2190
return -1; /* errno set by SMBC_server */
2199
2193
if (! srv->no_nt_session) {
2200
2194
ipc_srv = SMBC_attr_server(frame, context, server, share,
2201
2195
&workgroup, &user, &password);
2206
2200
ipc_srv = NULL;
2209
2203
if (! ipc_srv) {
2210
2204
TALLOC_FREE(frame);
2211
2205
return -1; /* errno set by SMBC_attr_server */
2214
2208
/* Are they asking to set the entire ACL? */
2215
2209
if (StrCaseCmp(name, "system.nt_sec_desc.*") == 0 ||
2216
2210
StrCaseCmp(name, "system.nt_sec_desc.*+") == 0) {
2219
2213
ret = cacl_set(context, talloc_tos(), srv->cli,
2220
2214
ipc_srv->cli, &ipc_srv->pol, path,
2234
2228
StrCaseCmp(name, "system.nt_sec_desc.group+") == 0 ||
2235
2229
StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 ||
2236
2230
StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) {
2239
2233
ret = cacl_set(context, talloc_tos(), srv->cli,
2240
2234
ipc_srv->cli, &ipc_srv->pol, path,
2310
2304
supported = supported_old;
2311
2305
retsize = sizeof(supported_old);
2314
2308
if (size == 0) {
2315
2309
return retsize;
2318
2312
if (retsize > size) {
2319
2313
errno = ERANGE;
2323
2317
/* this can't be strcpy() because there are embedded null characters */
2324
2318
memcpy(list, supported, retsize);
2325
2319
return retsize;