184
strncpy(dest, temp, max_dest_len);
184
strncpy(dest, temp, max_dest_len - 1);
185
dest[max_dest_len - 1] = '\0';
186
187
return err_count;
269
270
smbc_parse_path(SMBCCTX *context,
270
271
const char *fname,
272
char *workgroup, int workgroup_len,
271
273
char *server, int server_len,
272
274
char *share, int share_len,
273
275
char *path, int path_len,
284
286
server[0] = share[0] = path[0] = user[0] = password[0] = (char)0;
289
* Assume we wont find an authentication domain to parse, so default
290
* to the workgroup in the provided context.
292
if (workgroup != NULL) {
293
strncpy(workgroup, context->workgroup, workgroup_len - 1);
294
workgroup[workgroup_len - 1] = '\0';
285
297
if (options != NULL && options_len > 0) {
286
298
options[0] = (char)0;
373
strncpy(user, username, user_len); /* FIXME, domain */
376
strncpy(password, passwd, password_len);
385
if (domain[0] && workgroup) {
386
strncpy(workgroup, domain, workgroup_len - 1);
387
workgroup[workgroup_len - 1] = '\0';
391
strncpy(user, username, user_len - 1);
392
user[user_len - 1] = '\0';
396
strncpy(password, passwd, password_len - 1);
397
password[password_len - 1] = '\0';
394
safe_strcpy(path, p, path_len - 1);
417
* Prepend a leading slash if there's a file path, as required by
423
safe_strcpy(path + 1, p, path_len - 2);
396
426
all_string_sub(path, "/", "\\", 0);
530
560
workgroup, username);
532
562
if (!auth_called && !srv && (!username[0] || !password[0])) {
533
context->callbacks.auth_fn(server, share,
534
workgroup, sizeof(fstring),
535
username, sizeof(fstring),
536
password, sizeof(fstring));
563
if (context->internal->_auth_fn_with_context != NULL) {
564
context->internal->_auth_fn_with_context(
567
workgroup, sizeof(fstring),
568
username, sizeof(fstring),
569
password, sizeof(fstring));
571
context->callbacks.auth_fn(
573
workgroup, sizeof(fstring),
574
username, sizeof(fstring),
575
password, sizeof(fstring));
538
579
* However, smbc_auth_fn may have picked up info relating to
539
580
* an existing connection, so try for an existing connection
636
677
if (srv->cli.cnum == (uint16) -1) {
637
678
/* Ensure we have accurate auth info */
638
context->callbacks.auth_fn(server, share,
639
workgroup, sizeof(fstring),
640
username, sizeof(fstring),
641
password, sizeof(fstring));
679
if (context->internal->_auth_fn_with_context != NULL) {
680
context->internal->_auth_fn_with_context(
683
workgroup, sizeof(fstring),
684
username, sizeof(fstring),
685
password, sizeof(fstring));
687
context->callbacks.auth_fn(
689
workgroup, sizeof(fstring),
690
username, sizeof(fstring),
691
password, sizeof(fstring));
643
694
if (! cli_send_tconX(&srv->cli, share, "?????",
644
695
password, strlen(password)+1)) {
879
930
/* We didn't find a cached connection. Get the password */
880
931
if (*password == '\0') {
881
932
/* ... then retrieve it now. */
882
context->callbacks.auth_fn(server, share,
883
workgroup, sizeof(fstring),
884
username, sizeof(fstring),
885
password, sizeof(fstring));
933
if (context->internal->_auth_fn_with_context != NULL) {
934
context->internal->_auth_fn_with_context(
937
workgroup, sizeof(fstring),
938
username, sizeof(fstring),
939
password, sizeof(fstring));
941
context->callbacks.auth_fn(
943
workgroup, sizeof(fstring),
944
username, sizeof(fstring),
945
password, sizeof(fstring));
1014
1076
if (user[0] == (char)0) fstrcpy(user, context->user);
1016
fstrcpy(workgroup, context->workgroup);
1018
1078
srv = smbc_server(context, True,
1019
1079
server, share, workgroup, user, password);
1049
1109
if (!cli_resolve_path( "", &srv->cli, path, &targetcli, targetpath))
1051
1111
d_printf("Could not resolve %s\n", path);
1054
1115
/*d_printf(">>>open: resolved %s as %s\n", path, targetpath);*/
1178
1239
* the call to cli_read() instead of file->offset fixes a problem
1179
1240
* retrieving data at an offset greater than 4GB.
1181
off_t offset = file->offset;
1183
1244
if (!context || !context->internal ||
1184
1245
!context->internal->_initialized) {
1260
1324
pstring path, targetpath;
1261
1325
struct cli_state *targetcli;
1327
/* First check all pointers before dereferencing them */
1329
if (!context || !context->internal ||
1330
!context->internal->_initialized) {
1337
if (!file || !DLIST_CONTAINS(context->internal->_files, file)) {
1344
/* Check that the buffer exists ... */
1263
1353
offset = file->offset; /* See "offset" comment in smbc_read_ctx() */
1265
if (!context || !context->internal ||
1266
!context->internal->_initialized) {
1273
if (!file || !DLIST_CONTAINS(context->internal->_files, file)) {
1280
/* Check that the buffer exists ... */
1289
1355
/*d_printf(">>>write: parsing %s\n", file->fname);*/
1290
1356
if (smbc_parse_path(context, file->fname,
1291
1358
server, sizeof(server),
1292
1359
share, sizeof(share),
1293
1360
path, sizeof(path),
1457
1525
if (!srv->no_pathinfo2 &&
1458
1526
cli_qpathinfo2(targetcli, targetpath,
1459
c_time, a_time, m_time, NULL, size, mode, ino)) {
1527
NULL, a_time, m_time, c_time, size, mode, ino)) {
1502
* Get the create time of the file (if not provided); we'll need it in
1505
if (! srv->no_pathinfo && c_time == 0) {
1506
if (! cli_qpathinfo(&srv->cli, path,
1507
&c_time, NULL, NULL, NULL, NULL)) {
1508
/* qpathinfo not available */
1509
srv->no_pathinfo = True;
1512
* We got a creation time. Some OS versions don't
1513
* return a valid create time, though. If we got an
1514
* invalid time, start with the current time instead.
1516
if (c_time == 0 || c_time == (time_t) -1) {
1517
c_time = time(NULL);
1521
* We got a creation time. For sanity sake, since
1522
* there is no POSIX function to set the create time
1523
* of a file, if the existing create time is greater
1524
* than either of access time or modification time,
1525
* set create time to the smallest of those. This
1526
* ensure that the create time of a file is never
1527
* greater than its last access or modification time.
1529
if (c_time > a_time) c_time = a_time;
1530
if (c_time > m_time) c_time = m_time;
1535
1570
* First, try setpathinfo (if qpathinfo succeeded), for it is the
1536
1571
* modern function for "new code" to be using, and it works given a
1537
1572
* filename rather than requiring that the file be opened to have its
1658
1694
if (user[0] == (char)0) fstrcpy(user, context->user);
1660
fstrcpy(workgroup, context->workgroup);
1662
1696
srv = smbc_server(context, True,
1663
1697
server, share, workgroup, user, password);
1762
1796
DEBUG(4, ("smbc_rename(%s,%s)\n", oname, nname));
1764
1798
smbc_parse_path(ocontext, oname,
1799
workgroup, sizeof(workgroup),
1765
1800
server1, sizeof(server1),
1766
1801
share1, sizeof(share1),
1767
1802
path1, sizeof(path1),
1772
1807
if (user1[0] == (char)0) fstrcpy(user1, ocontext->user);
1774
1809
smbc_parse_path(ncontext, nname,
1775
1811
server2, sizeof(server2),
1776
1812
share2, sizeof(share2),
1777
1813
path2, sizeof(path2),
1794
fstrcpy(workgroup, ocontext->workgroup);
1796
1830
srv = smbc_server(ocontext, True,
1797
1831
server1, share1, workgroup, user1, password1);
2049
2084
DEBUG(4, ("smbc_stat(%s)\n", fname));
2051
2086
if (smbc_parse_path(context, fname,
2087
workgroup, sizeof(workgroup),
2052
2088
server, sizeof(server),
2053
2089
share, sizeof(share),
2054
2090
path, sizeof(path),
2062
2098
if (user[0] == (char)0) fstrcpy(user, context->user);
2064
fstrcpy(workgroup, context->workgroup);
2066
2100
srv = smbc_server(context, True,
2067
2101
server, share, workgroup, user, password);
2157
2192
/*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/
2159
2194
if (!cli_qfileinfo(targetcli, file->cli_fd, &mode, &size,
2160
&c_time, &a_time, &m_time, NULL, &ino)) {
2195
NULL, &a_time, &m_time, &c_time, &ino)) {
2161
2196
if (!cli_getattrE(targetcli, file->cli_fd, &mode, &size,
2162
2197
&c_time, &a_time, &m_time)) {
2270
2305
dirent->commentlen = comment_len;
2271
2306
dirent->dirlen = size;
2309
* dirent->namelen + 1 includes the null (no null termination needed)
2310
* Ditto for dirent->commentlen.
2311
* The space for the two null bytes was allocated.
2273
2313
strncpy(dirent->name, (name?name:""), dirent->namelen + 1);
2275
2314
dirent->comment = (char *)(&dirent->name + dirent->namelen + 1);
2276
2315
strncpy(dirent->comment, (comment?comment:""), dirent->commentlen + 1);
2934
2984
dest->comment = dest->name + dest->namelen + 1;
2936
2986
/* Copy the comment */
2937
strncpy(dest->comment, src->comment, max_namebuf_len);
2939
/* Ensure the comment is null terminated */
2940
if (max_namebuf_len > src->commentlen) {
2941
dest->comment[src->commentlen] = '\0';
2943
dest->comment[max_namebuf_len - 1] = '\0';
2987
strncpy(dest->comment, src->comment, max_namebuf_len - 1);
2988
dest->comment[max_namebuf_len - 1] = '\0';
2946
2990
/* Save other fields */
2947
2991
dest->smbc_type = src->smbc_type;
3156
3200
DEBUG(4, ("smbc_mkdir(%s)\n", fname));
3158
3202
if (smbc_parse_path(context, fname,
3203
workgroup, sizeof(workgroup),
3159
3204
server, sizeof(server),
3160
3205
share, sizeof(share),
3161
3206
path, sizeof(path),
3169
3214
if (user[0] == (char)0) fstrcpy(user, context->user);
3171
fstrcpy(workgroup, context->workgroup);
3173
3216
srv = smbc_server(context, True,
3174
3217
server, share, workgroup, user, password);
3253
3296
DEBUG(4, ("smbc_rmdir(%s)\n", fname));
3255
3298
if (smbc_parse_path(context, fname,
3299
workgroup, sizeof(workgroup),
3256
3300
server, sizeof(server),
3257
3301
share, sizeof(share),
3258
3302
path, sizeof(path),
3267
3311
if (user[0] == (char)0) fstrcpy(user, context->user);
3269
fstrcpy(workgroup, context->workgroup);
3271
3313
srv = smbc_server(context, True,
3272
3314
server, share, workgroup, user, password);
3507
3549
DEBUG(4, ("smbc_chmod(%s, 0%3o)\n", fname, newmode));
3509
3551
if (smbc_parse_path(context, fname,
3552
workgroup, sizeof(workgroup),
3510
3553
server, sizeof(server),
3511
3554
share, sizeof(share),
3512
3555
path, sizeof(path),
3520
3563
if (user[0] == (char)0) fstrcpy(user, context->user);
3522
fstrcpy(workgroup, context->workgroup);
3524
3565
srv = smbc_server(context, True,
3525
3566
server, share, workgroup, user, password);
3586
3627
char atimebuf[32];
3587
3628
char mtimebuf[32];
3589
strncpy(atimebuf, ctime(&a_time), sizeof(atimebuf));
3630
strncpy(atimebuf, ctime(&a_time), sizeof(atimebuf) - 1);
3590
3631
atimebuf[sizeof(atimebuf) - 1] = '\0';
3591
3632
if ((p = strchr(atimebuf, '\n')) != NULL) {
3595
strncpy(mtimebuf, ctime(&m_time), sizeof(mtimebuf));
3636
strncpy(mtimebuf, ctime(&m_time), sizeof(mtimebuf) - 1);
3596
3637
mtimebuf[sizeof(mtimebuf) - 1] = '\0';
3597
3638
if ((p = strchr(mtimebuf, '\n')) != NULL) {
3616
3658
if (user[0] == (char)0) fstrcpy(user, context->user);
3618
fstrcpy(workgroup, context->workgroup);
3620
3660
srv = smbc_server(context, True,
3621
3661
server, share, workgroup, user, password);
3752
3792
if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_names(pipe_hnd, ipc_cli->mem_ctx,
3753
pol, 1, &str, &sids,
3793
pol, 1, &str, NULL, &sids,
3755
3795
result = False;
3903
aces = SMB_CALLOC_ARRAY(SEC_ACE, 1+(*the_acl)->num_aces);
3943
if ((aces = SMB_CALLOC_ARRAY(SEC_ACE, 1+(*the_acl)->num_aces)) == NULL) {
3904
3946
memcpy(aces, (*the_acl)->ace, (*the_acl)->num_aces * sizeof(SEC_ACE));
3905
3947
memcpy(aces+(*the_acl)->num_aces, ace, sizeof(SEC_ACE));
3906
3948
newacl = make_sec_acl(ctx, (*the_acl)->revision,
3938
3980
if (StrnCaseCmp(tok,"OWNER:", 6) == 0) {
3982
DEBUG(5, ("OWNER specified more than once!\n"));
3939
3985
owner_sid = SMB_CALLOC_ARRAY(DOM_SID, 1);
3940
3986
if (!owner_sid ||
3941
3987
!convert_string_to_sid(ipc_cli, pol,
3943
3989
owner_sid, tok+6)) {
3944
3990
DEBUG(5, ("Failed to parse owner sid\n"));
3950
3996
if (StrnCaseCmp(tok,"OWNER+:", 7) == 0) {
3998
DEBUG(5, ("OWNER specified more than once!\n"));
3951
4001
owner_sid = SMB_CALLOC_ARRAY(DOM_SID, 1);
3952
4002
if (!owner_sid ||
3953
4003
!convert_string_to_sid(ipc_cli, pol,
3955
4005
owner_sid, tok+7)) {
3956
4006
DEBUG(5, ("Failed to parse owner sid\n"));
3962
4012
if (StrnCaseCmp(tok,"GROUP:", 6) == 0) {
4014
DEBUG(5, ("GROUP specified more than once!\n"));
3963
4017
grp_sid = SMB_CALLOC_ARRAY(DOM_SID, 1);
3964
4018
if (!grp_sid ||
3965
4019
!convert_string_to_sid(ipc_cli, pol,
3967
4021
grp_sid, tok+6)) {
3968
4022
DEBUG(5, ("Failed to parse group sid\n"));
3974
4028
if (StrnCaseCmp(tok,"GROUP+:", 7) == 0) {
4030
DEBUG(5, ("GROUP specified more than once!\n"));
3975
4033
grp_sid = SMB_CALLOC_ARRAY(DOM_SID, 1);
3976
4034
if (!grp_sid ||
3977
4035
!convert_string_to_sid(ipc_cli, pol,
3979
4037
grp_sid, tok+6)) {
3980
4038
DEBUG(5, ("Failed to parse group sid\n"));
3988
4046
if (!parse_ace(ipc_cli, pol, &ace, numeric, tok+4)) {
3989
4047
DEBUG(5, ("Failed to parse ACL %s\n", tok));
3992
4050
if(!add_ace(&dacl, &ace, ctx)) {
3993
4051
DEBUG(5, ("Failed to add ACL %s\n", tok));
4001
4059
if (!parse_ace(ipc_cli, pol, &ace, False, tok+5)) {
4002
4060
DEBUG(5, ("Failed to parse ACL %s\n", tok));
4005
4063
if(!add_ace(&dacl, &ace, ctx)) {
4006
4064
DEBUG(5, ("Failed to add ACL %s\n", tok));
4012
4070
DEBUG(5, ("Failed to parse security descriptor\n"));
4016
4074
ret = make_sec_desc(ctx, revision, SEC_DESC_SELF_RELATIVE,
4017
4075
owner_sid, grp_sid, NULL, dacl, &sd_size);
4019
4078
SAFE_FREE(grp_sid);
4020
4079
SAFE_FREE(owner_sid);
4808
4867
CONST_DISCARD(char *, the_acl));
4875
/* SMBC_XATTR_MODE_REMOVE_ALL is the only caller
4876
that doesn't deref sd */
4878
if (!sd && (mode != SMBC_XATTR_MODE_REMOVE_ALL)) {
4816
4883
/* The desired access below is the only one I could find that works
4817
4884
with NT4, W2KP and Samba */
4999
5066
fname, name, (int) size, (const char*)value));
5001
5068
if (smbc_parse_path(context, fname,
5069
workgroup, sizeof(workgroup),
5002
5070
server, sizeof(server),
5003
5071
share, sizeof(share),
5004
5072
path, sizeof(path),
5012
5080
if (user[0] == (char)0) fstrcpy(user, context->user);
5014
fstrcpy(workgroup, context->workgroup);
5016
5082
srv = smbc_server(context, True,
5017
5083
server, share, workgroup, user, password);
5267
5333
DEBUG(4, ("smbc_getxattr(%s, %s)\n", fname, name));
5269
5335
if (smbc_parse_path(context, fname,
5336
workgroup, sizeof(workgroup),
5270
5337
server, sizeof(server),
5271
5338
share, sizeof(share),
5272
5339
path, sizeof(path),
5280
5347
if (user[0] == (char)0) fstrcpy(user, context->user);
5282
fstrcpy(workgroup, context->workgroup);
5284
5349
srv = smbc_server(context, True,
5285
5350
server, share, workgroup, user, password);
5384
5449
DEBUG(4, ("smbc_removexattr(%s, %s)\n", fname, name));
5386
5451
if (smbc_parse_path(context, fname,
5452
workgroup, sizeof(workgroup),
5387
5453
server, sizeof(server),
5388
5454
share, sizeof(share),
5389
5455
path, sizeof(path),
5397
5463
if (user[0] == (char)0) fstrcpy(user, context->user);
5399
fstrcpy(workgroup, context->workgroup);
5401
5465
srv = smbc_server(context, True,
5402
5466
server, share, workgroup, user, password);
5676
5741
DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname));
5678
5743
if (smbc_parse_path(context, fname,
5744
workgroup, sizeof(workgroup),
5679
5745
server, sizeof(server),
5680
5746
share, sizeof(share),
5681
5747
path, sizeof(path),
5689
5755
if (user[0] == (char)0) fstrcpy(user, context->user);
5691
fstrcpy(workgroup, context->workgroup);
5693
5757
srv = smbc_server(context, True,
5694
5758
server, share, workgroup, user, password);
5747
5811
DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname));
5749
5813
if (smbc_parse_path(context, fname,
5814
workgroup, sizeof(workgroup),
5750
5815
server, sizeof(server),
5751
5816
share, sizeof(share),
5752
5817
path, sizeof(path),
5760
5825
if (user[0] == (char)0) fstrcpy(user, context->user);
5762
fstrcpy(workgroup, context->workgroup);
5764
5827
srv = smbc_server(context, True,
5765
5828
server, share, workgroup, user, password);
5948
6012
smbc_option_set(SMBCCTX *context,
5949
6013
char *option_name,
5954
va_start(args, option_name);
5956
if (strcmp(option_name, "debug_stderr") == 0) {
5958
* Log to standard error instead of standard output.
5960
* optional parameters: none (it can't be turned off once on)
5962
context->internal->_debug_stderr = True;
6016
if (strcmp(option_name, "debug_stderr") == 0) {
6018
* Log to standard error instead of standard output.
6020
context->internal->_debug_stderr =
6021
(option_value == NULL ? False : True);
6022
} else if (strcmp(option_name, "auth_function") == 0) {
6024
* Use the new-style authentication function which includes
6027
context->internal->_auth_fn_with_context = option_value;
6028
} else if (strcmp(option_name, "user_data") == 0) {
6030
* Save a user data handle which may be retrieved by the user
6031
* with smbc_option_get()
6033
context->internal->_user_data = option_value;
6039
* Retrieve the current value of an option
6042
smbc_option_get(SMBCCTX *context,
6045
if (strcmp(option_name, "debug_stderr") == 0) {
6047
* Log to standard error instead of standard output.
6049
#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
6050
return (void *) (intptr_t) context->internal->_debug_stderr;
6052
return (void *) context->internal->_debug_stderr;
6054
} else if (strcmp(option_name, "auth_function") == 0) {
6056
* Use the new-style authentication function which includes
6059
return (void *) context->internal->_auth_fn_with_context;
6060
} else if (strcmp(option_name, "user_data") == 0) {
6062
* Save a user data handle which may be retrieved by the user
6063
* with smbc_option_get()
6065
return context->internal->_user_data;
6025
6129
home = getenv("HOME");
6027
6131
slprintf(conf, sizeof(conf), "%s/.smb/smb.conf", home);
6028
if (lp_load(conf, True, False, False)) {
6132
if (lp_load(conf, True, False, False, True)) {
6029
6133
conf_loaded = True;
6031
6135
DEBUG(5, ("Could not load config file: %s\n",
6044
if (!lp_load(dyn_CONFIGFILE, True, False, False)) {
6148
if (!lp_load(dyn_CONFIGFILE, True, False, False, False)) {
6045
6149
DEBUG(5, ("Could not load config file: %s\n",
6046
6150
dyn_CONFIGFILE));
6047
6151
} else if (home) {
6053
6157
slprintf(conf, sizeof(conf),
6054
6158
"%s/.smb/smb.conf.append", home);
6055
if (!lp_load(conf, True, False, False)) {
6159
if (!lp_load(conf, True, False, False, False)) {
6057
6161
("Could not append config file: "