00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "includes.h"
00023
00024
00025
00026
00027
00028
00029 static BOOL cli_link_internal(struct cli_state *cli, const char *oldname, const char *newname, BOOL hard_link)
00030 {
00031 unsigned int data_len = 0;
00032 unsigned int param_len = 0;
00033 uint16 setup = TRANSACT2_SETPATHINFO;
00034 char param[sizeof(pstring)+6];
00035 pstring data;
00036 char *rparam=NULL, *rdata=NULL;
00037 char *p;
00038 size_t oldlen = 2*(strlen(oldname)+1);
00039 size_t newlen = 2*(strlen(newname)+1);
00040
00041 memset(param, 0, sizeof(param));
00042 SSVAL(param,0,hard_link ? SMB_SET_FILE_UNIX_HLINK : SMB_SET_FILE_UNIX_LINK);
00043 p = ¶m[6];
00044
00045 p += clistr_push(cli, p, newname, MIN(newlen, sizeof(param)-6), STR_TERMINATE);
00046 param_len = PTR_DIFF(p, param);
00047
00048 p = data;
00049 p += clistr_push(cli, p, oldname, MIN(oldlen,sizeof(data)), STR_TERMINATE);
00050 data_len = PTR_DIFF(p, data);
00051
00052 if (!cli_send_trans(cli, SMBtrans2,
00053 NULL,
00054 -1, 0,
00055 &setup, 1, 0,
00056 param, param_len, 2,
00057 (char *)&data, data_len, cli->max_xmit
00058 )) {
00059 return False;
00060 }
00061
00062 if (!cli_receive_trans(cli, SMBtrans2,
00063 &rparam, ¶m_len,
00064 &rdata, &data_len)) {
00065 return False;
00066 }
00067
00068 SAFE_FREE(rdata);
00069 SAFE_FREE(rparam);
00070
00071 return True;
00072 }
00073
00074
00075
00076
00077
00078 uint32 unix_perms_to_wire(mode_t perms)
00079 {
00080 unsigned int ret = 0;
00081
00082 ret |= ((perms & S_IXOTH) ? UNIX_X_OTH : 0);
00083 ret |= ((perms & S_IWOTH) ? UNIX_W_OTH : 0);
00084 ret |= ((perms & S_IROTH) ? UNIX_R_OTH : 0);
00085 ret |= ((perms & S_IXGRP) ? UNIX_X_GRP : 0);
00086 ret |= ((perms & S_IWGRP) ? UNIX_W_GRP : 0);
00087 ret |= ((perms & S_IRGRP) ? UNIX_R_GRP : 0);
00088 ret |= ((perms & S_IXUSR) ? UNIX_X_USR : 0);
00089 ret |= ((perms & S_IWUSR) ? UNIX_W_USR : 0);
00090 ret |= ((perms & S_IRUSR) ? UNIX_R_USR : 0);
00091 #ifdef S_ISVTX
00092 ret |= ((perms & S_ISVTX) ? UNIX_STICKY : 0);
00093 #endif
00094 #ifdef S_ISGID
00095 ret |= ((perms & S_ISGID) ? UNIX_SET_GID : 0);
00096 #endif
00097 #ifdef S_ISUID
00098 ret |= ((perms & S_ISUID) ? UNIX_SET_UID : 0);
00099 #endif
00100 return ret;
00101 }
00102
00103
00104
00105
00106
00107 mode_t wire_perms_to_unix(uint32 perms)
00108 {
00109 mode_t ret = (mode_t)0;
00110
00111 ret |= ((perms & UNIX_X_OTH) ? S_IXOTH : 0);
00112 ret |= ((perms & UNIX_W_OTH) ? S_IWOTH : 0);
00113 ret |= ((perms & UNIX_R_OTH) ? S_IROTH : 0);
00114 ret |= ((perms & UNIX_X_GRP) ? S_IXGRP : 0);
00115 ret |= ((perms & UNIX_W_GRP) ? S_IWGRP : 0);
00116 ret |= ((perms & UNIX_R_GRP) ? S_IRGRP : 0);
00117 ret |= ((perms & UNIX_X_USR) ? S_IXUSR : 0);
00118 ret |= ((perms & UNIX_W_USR) ? S_IWUSR : 0);
00119 ret |= ((perms & UNIX_R_USR) ? S_IRUSR : 0);
00120 #ifdef S_ISVTX
00121 ret |= ((perms & UNIX_STICKY) ? S_ISVTX : 0);
00122 #endif
00123 #ifdef S_ISGID
00124 ret |= ((perms & UNIX_SET_GID) ? S_ISGID : 0);
00125 #endif
00126 #ifdef S_ISUID
00127 ret |= ((perms & UNIX_SET_UID) ? S_ISUID : 0);
00128 #endif
00129 return ret;
00130 }
00131
00132
00133
00134
00135
00136 static mode_t unix_filetype_from_wire(uint32 wire_type)
00137 {
00138 switch (wire_type) {
00139 case UNIX_TYPE_FILE:
00140 return S_IFREG;
00141 case UNIX_TYPE_DIR:
00142 return S_IFDIR;
00143 #ifdef S_IFLNK
00144 case UNIX_TYPE_SYMLINK:
00145 return S_IFLNK;
00146 #endif
00147 #ifdef S_IFCHR
00148 case UNIX_TYPE_CHARDEV:
00149 return S_IFCHR;
00150 #endif
00151 #ifdef S_IFBLK
00152 case UNIX_TYPE_BLKDEV:
00153 return S_IFBLK;
00154 #endif
00155 #ifdef S_IFIFO
00156 case UNIX_TYPE_FIFO:
00157 return S_IFIFO;
00158 #endif
00159 #ifdef S_IFSOCK
00160 case UNIX_TYPE_SOCKET:
00161 return S_IFSOCK;
00162 #endif
00163 default:
00164 return (mode_t)0;
00165 }
00166 }
00167
00168
00169
00170
00171
00172 BOOL cli_unix_getfacl(struct cli_state *cli, const char *name, size_t *prb_size, char **retbuf)
00173 {
00174 unsigned int param_len = 0;
00175 unsigned int data_len = 0;
00176 uint16 setup = TRANSACT2_QPATHINFO;
00177 char param[sizeof(pstring)+6];
00178 char *rparam=NULL, *rdata=NULL;
00179 char *p;
00180
00181 p = param;
00182 memset(p, 0, 6);
00183 SSVAL(p, 0, SMB_QUERY_POSIX_ACL);
00184 p += 6;
00185 p += clistr_push(cli, p, name, sizeof(pstring)-6, STR_TERMINATE);
00186 param_len = PTR_DIFF(p, param);
00187
00188 if (!cli_send_trans(cli, SMBtrans2,
00189 NULL,
00190 -1, 0,
00191 &setup, 1, 0,
00192 param, param_len, 2,
00193 NULL, 0, cli->max_xmit
00194 )) {
00195 return False;
00196 }
00197
00198 if (!cli_receive_trans(cli, SMBtrans2,
00199 &rparam, ¶m_len,
00200 &rdata, &data_len)) {
00201 return False;
00202 }
00203
00204 if (data_len < 6) {
00205 SAFE_FREE(rdata);
00206 SAFE_FREE(rparam);
00207 return False;
00208 }
00209
00210 SAFE_FREE(rparam);
00211 *retbuf = rdata;
00212 *prb_size = (size_t)data_len;
00213
00214 return True;
00215 }
00216
00217
00218
00219
00220
00221 BOOL cli_unix_stat(struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbuf)
00222 {
00223 unsigned int param_len = 0;
00224 unsigned int data_len = 0;
00225 uint16 setup = TRANSACT2_QPATHINFO;
00226 char param[sizeof(pstring)+6];
00227 char *rparam=NULL, *rdata=NULL;
00228 char *p;
00229
00230 ZERO_STRUCTP(sbuf);
00231
00232 p = param;
00233 memset(p, 0, 6);
00234 SSVAL(p, 0, SMB_QUERY_FILE_UNIX_BASIC);
00235 p += 6;
00236 p += clistr_push(cli, p, name, sizeof(pstring)-6, STR_TERMINATE);
00237 param_len = PTR_DIFF(p, param);
00238
00239 if (!cli_send_trans(cli, SMBtrans2,
00240 NULL,
00241 -1, 0,
00242 &setup, 1, 0,
00243 param, param_len, 2,
00244 NULL, 0, cli->max_xmit
00245 )) {
00246 return False;
00247 }
00248
00249 if (!cli_receive_trans(cli, SMBtrans2,
00250 &rparam, ¶m_len,
00251 &rdata, &data_len)) {
00252 return False;
00253 }
00254
00255 if (data_len < 96) {
00256 SAFE_FREE(rdata);
00257 SAFE_FREE(rparam);
00258 return False;
00259 }
00260
00261 sbuf->st_size = IVAL2_TO_SMB_BIG_UINT(rdata,0);
00262 sbuf->st_blocks = IVAL2_TO_SMB_BIG_UINT(rdata,8);
00263 #if defined (HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
00264 sbuf->st_blocks /= STAT_ST_BLOCKSIZE;
00265 #else
00266
00267 sbuf->st_blocks /= 512;
00268 #endif
00269 set_ctimespec(sbuf, interpret_long_date(rdata + 16));
00270 set_atimespec(sbuf, interpret_long_date(rdata + 24));
00271 set_mtimespec(sbuf, interpret_long_date(rdata + 32));
00272
00273 sbuf->st_uid = (uid_t) IVAL(rdata,40);
00274 sbuf->st_gid = (gid_t) IVAL(rdata,48);
00275 sbuf->st_mode |= unix_filetype_from_wire(IVAL(rdata, 56));
00276 #if defined(HAVE_MAKEDEV)
00277 {
00278 uint32 dev_major = IVAL(rdata,60);
00279 uint32 dev_minor = IVAL(rdata,68);
00280 sbuf->st_rdev = makedev(dev_major, dev_minor);
00281 }
00282 #endif
00283 sbuf->st_ino = (SMB_INO_T)IVAL2_TO_SMB_BIG_UINT(rdata,76);
00284 sbuf->st_mode |= wire_perms_to_unix(IVAL(rdata,84));
00285 sbuf->st_nlink = IVAL(rdata,92);
00286
00287 SAFE_FREE(rdata);
00288 SAFE_FREE(rparam);
00289
00290 return True;
00291 }
00292
00293
00294
00295
00296
00297 BOOL cli_unix_symlink(struct cli_state *cli, const char *oldname, const char *newname)
00298 {
00299 return cli_link_internal(cli, oldname, newname, False);
00300 }
00301
00302
00303
00304
00305
00306 BOOL cli_unix_hardlink(struct cli_state *cli, const char *oldname, const char *newname)
00307 {
00308 return cli_link_internal(cli, oldname, newname, True);
00309 }
00310
00311
00312
00313
00314
00315 static BOOL cli_unix_chmod_chown_internal(struct cli_state *cli, const char *fname, uint32 mode, uint32 uid, uint32 gid)
00316 {
00317 unsigned int data_len = 0;
00318 unsigned int param_len = 0;
00319 uint16 setup = TRANSACT2_SETPATHINFO;
00320 char param[sizeof(pstring)+6];
00321 char data[100];
00322 char *rparam=NULL, *rdata=NULL;
00323 char *p;
00324
00325 memset(param, 0, sizeof(param));
00326 memset(data, 0, sizeof(data));
00327 SSVAL(param,0,SMB_SET_FILE_UNIX_BASIC);
00328 p = ¶m[6];
00329
00330 p += clistr_push(cli, p, fname, -1, STR_TERMINATE);
00331 param_len = PTR_DIFF(p, param);
00332
00333 memset(data, 0xff, 40);
00334
00335 SIVAL(data,40,uid);
00336 SIVAL(data,48,gid);
00337 SIVAL(data,84,mode);
00338
00339 data_len = 100;
00340
00341 if (!cli_send_trans(cli, SMBtrans2,
00342 NULL,
00343 -1, 0,
00344 &setup, 1, 0,
00345 param, param_len, 2,
00346 (char *)&data, data_len, cli->max_xmit
00347 )) {
00348 return False;
00349 }
00350
00351 if (!cli_receive_trans(cli, SMBtrans2,
00352 &rparam, ¶m_len,
00353 &rdata, &data_len)) {
00354 return False;
00355 }
00356
00357 SAFE_FREE(rdata);
00358 SAFE_FREE(rparam);
00359
00360 return True;
00361 }
00362
00363
00364
00365
00366
00367 BOOL cli_unix_chmod(struct cli_state *cli, const char *fname, mode_t mode)
00368 {
00369 return cli_unix_chmod_chown_internal(cli, fname,
00370 unix_perms_to_wire(mode), SMB_UID_NO_CHANGE, SMB_GID_NO_CHANGE);
00371 }
00372
00373
00374
00375
00376
00377 BOOL cli_unix_chown(struct cli_state *cli, const char *fname, uid_t uid, gid_t gid)
00378 {
00379 return cli_unix_chmod_chown_internal(cli, fname, SMB_MODE_NO_CHANGE, (uint32)uid, (uint32)gid);
00380 }
00381
00382
00383
00384
00385
00386 BOOL cli_rename(struct cli_state *cli, const char *fname_src, const char *fname_dst)
00387 {
00388 char *p;
00389
00390 memset(cli->outbuf,'\0',smb_size);
00391 memset(cli->inbuf,'\0',smb_size);
00392
00393 set_message(cli->outbuf,1, 0, True);
00394
00395 SCVAL(cli->outbuf,smb_com,SMBmv);
00396 SSVAL(cli->outbuf,smb_tid,cli->cnum);
00397 cli_setup_packet(cli);
00398
00399 SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN | aDIR);
00400
00401 p = smb_buf(cli->outbuf);
00402 *p++ = 4;
00403 p += clistr_push(cli, p, fname_src, -1, STR_TERMINATE);
00404 *p++ = 4;
00405 p += clistr_push(cli, p, fname_dst, -1, STR_TERMINATE);
00406
00407 cli_setup_bcc(cli, p);
00408
00409 cli_send_smb(cli);
00410 if (!cli_receive_smb(cli))
00411 return False;
00412
00413 if (cli_is_error(cli))
00414 return False;
00415
00416 return True;
00417 }
00418
00419
00420
00421
00422
00423 BOOL cli_ntrename(struct cli_state *cli, const char *fname_src, const char *fname_dst)
00424 {
00425 char *p;
00426
00427 memset(cli->outbuf,'\0',smb_size);
00428 memset(cli->inbuf,'\0',smb_size);
00429
00430 set_message(cli->outbuf, 4, 0, True);
00431
00432 SCVAL(cli->outbuf,smb_com,SMBntrename);
00433 SSVAL(cli->outbuf,smb_tid,cli->cnum);
00434 cli_setup_packet(cli);
00435
00436 SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN | aDIR);
00437 SSVAL(cli->outbuf,smb_vwv1, RENAME_FLAG_RENAME);
00438
00439 p = smb_buf(cli->outbuf);
00440 *p++ = 4;
00441 p += clistr_push(cli, p, fname_src, -1, STR_TERMINATE);
00442 *p++ = 4;
00443 p += clistr_push(cli, p, fname_dst, -1, STR_TERMINATE);
00444
00445 cli_setup_bcc(cli, p);
00446
00447 cli_send_smb(cli);
00448 if (!cli_receive_smb(cli))
00449 return False;
00450
00451 if (cli_is_error(cli))
00452 return False;
00453
00454 return True;
00455 }
00456
00457
00458
00459
00460
00461 BOOL cli_nt_hardlink(struct cli_state *cli, const char *fname_src, const char *fname_dst)
00462 {
00463 char *p;
00464
00465 memset(cli->outbuf,'\0',smb_size);
00466 memset(cli->inbuf,'\0',smb_size);
00467
00468 set_message(cli->outbuf, 4, 0, True);
00469
00470 SCVAL(cli->outbuf,smb_com,SMBntrename);
00471 SSVAL(cli->outbuf,smb_tid,cli->cnum);
00472 cli_setup_packet(cli);
00473
00474 SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN | aDIR);
00475 SSVAL(cli->outbuf,smb_vwv1, RENAME_FLAG_HARD_LINK);
00476
00477 p = smb_buf(cli->outbuf);
00478 *p++ = 4;
00479 p += clistr_push(cli, p, fname_src, -1, STR_TERMINATE);
00480 *p++ = 4;
00481 p += clistr_push(cli, p, fname_dst, -1, STR_TERMINATE);
00482
00483 cli_setup_bcc(cli, p);
00484
00485 cli_send_smb(cli);
00486 if (!cli_receive_smb(cli))
00487 return False;
00488
00489 if (cli_is_error(cli))
00490 return False;
00491
00492 return True;
00493 }
00494
00495
00496
00497
00498
00499 BOOL cli_unlink_full(struct cli_state *cli, const char *fname, uint16 attrs)
00500 {
00501 char *p;
00502
00503 memset(cli->outbuf,'\0',smb_size);
00504 memset(cli->inbuf,'\0',smb_size);
00505
00506 set_message(cli->outbuf,1, 0,True);
00507
00508 SCVAL(cli->outbuf,smb_com,SMBunlink);
00509 SSVAL(cli->outbuf,smb_tid,cli->cnum);
00510 cli_setup_packet(cli);
00511
00512 SSVAL(cli->outbuf,smb_vwv0, attrs);
00513
00514 p = smb_buf(cli->outbuf);
00515 *p++ = 4;
00516 p += clistr_push(cli, p, fname, -1, STR_TERMINATE);
00517
00518 cli_setup_bcc(cli, p);
00519 cli_send_smb(cli);
00520 if (!cli_receive_smb(cli)) {
00521 return False;
00522 }
00523
00524 if (cli_is_error(cli)) {
00525 return False;
00526 }
00527
00528 return True;
00529 }
00530
00531
00532
00533
00534
00535 BOOL cli_unlink(struct cli_state *cli, const char *fname)
00536 {
00537 return cli_unlink_full(cli, fname, aSYSTEM | aHIDDEN);
00538 }
00539
00540
00541
00542
00543
00544 BOOL cli_mkdir(struct cli_state *cli, const char *dname)
00545 {
00546 char *p;
00547
00548 memset(cli->outbuf,'\0',smb_size);
00549 memset(cli->inbuf,'\0',smb_size);
00550
00551 set_message(cli->outbuf,0, 0,True);
00552
00553 SCVAL(cli->outbuf,smb_com,SMBmkdir);
00554 SSVAL(cli->outbuf,smb_tid,cli->cnum);
00555 cli_setup_packet(cli);
00556
00557 p = smb_buf(cli->outbuf);
00558 *p++ = 4;
00559 p += clistr_push(cli, p, dname, -1, STR_TERMINATE);
00560
00561 cli_setup_bcc(cli, p);
00562
00563 cli_send_smb(cli);
00564 if (!cli_receive_smb(cli)) {
00565 return False;
00566 }
00567
00568 if (cli_is_error(cli)) {
00569 return False;
00570 }
00571
00572 return True;
00573 }
00574
00575
00576
00577
00578
00579 BOOL cli_rmdir(struct cli_state *cli, const char *dname)
00580 {
00581 char *p;
00582
00583 memset(cli->outbuf,'\0',smb_size);
00584 memset(cli->inbuf,'\0',smb_size);
00585
00586 set_message(cli->outbuf,0, 0, True);
00587
00588 SCVAL(cli->outbuf,smb_com,SMBrmdir);
00589 SSVAL(cli->outbuf,smb_tid,cli->cnum);
00590 cli_setup_packet(cli);
00591
00592 p = smb_buf(cli->outbuf);
00593 *p++ = 4;
00594 p += clistr_push(cli, p, dname, -1, STR_TERMINATE);
00595
00596 cli_setup_bcc(cli, p);
00597
00598 cli_send_smb(cli);
00599 if (!cli_receive_smb(cli)) {
00600 return False;
00601 }
00602
00603 if (cli_is_error(cli)) {
00604 return False;
00605 }
00606
00607 return True;
00608 }
00609
00610
00611
00612
00613
00614 int cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag)
00615 {
00616 unsigned int data_len = 1;
00617 unsigned int param_len = 6;
00618 uint16 setup = TRANSACT2_SETFILEINFO;
00619 pstring param;
00620 unsigned char data;
00621 char *rparam=NULL, *rdata=NULL;
00622
00623 memset(param, 0, param_len);
00624 SSVAL(param,0,fnum);
00625 SSVAL(param,2,SMB_SET_FILE_DISPOSITION_INFO);
00626
00627 data = flag ? 1 : 0;
00628
00629 if (!cli_send_trans(cli, SMBtrans2,
00630 NULL,
00631 -1, 0,
00632 &setup, 1, 0,
00633 param, param_len, 2,
00634 (char *)&data, data_len, cli->max_xmit
00635 )) {
00636 return False;
00637 }
00638
00639 if (!cli_receive_trans(cli, SMBtrans2,
00640 &rparam, ¶m_len,
00641 &rdata, &data_len)) {
00642 return False;
00643 }
00644
00645 SAFE_FREE(rdata);
00646 SAFE_FREE(rparam);
00647
00648 return True;
00649 }
00650
00651
00652
00653
00654
00655
00656 int cli_nt_create_full(struct cli_state *cli, const char *fname,
00657 uint32 CreatFlags, uint32 DesiredAccess,
00658 uint32 FileAttributes, uint32 ShareAccess,
00659 uint32 CreateDisposition, uint32 CreateOptions,
00660 uint8 SecuityFlags)
00661 {
00662 char *p;
00663 int len;
00664
00665 memset(cli->outbuf,'\0',smb_size);
00666 memset(cli->inbuf,'\0',smb_size);
00667
00668 set_message(cli->outbuf,24,0,True);
00669
00670 SCVAL(cli->outbuf,smb_com,SMBntcreateX);
00671 SSVAL(cli->outbuf,smb_tid,cli->cnum);
00672 cli_setup_packet(cli);
00673
00674 SSVAL(cli->outbuf,smb_vwv0,0xFF);
00675 if (cli->use_oplocks)
00676 CreatFlags |= (REQUEST_OPLOCK|REQUEST_BATCH_OPLOCK);
00677
00678 SIVAL(cli->outbuf,smb_ntcreate_Flags, CreatFlags);
00679 SIVAL(cli->outbuf,smb_ntcreate_RootDirectoryFid, 0x0);
00680 SIVAL(cli->outbuf,smb_ntcreate_DesiredAccess, DesiredAccess);
00681 SIVAL(cli->outbuf,smb_ntcreate_FileAttributes, FileAttributes);
00682 SIVAL(cli->outbuf,smb_ntcreate_ShareAccess, ShareAccess);
00683 SIVAL(cli->outbuf,smb_ntcreate_CreateDisposition, CreateDisposition);
00684 SIVAL(cli->outbuf,smb_ntcreate_CreateOptions, CreateOptions);
00685 SIVAL(cli->outbuf,smb_ntcreate_ImpersonationLevel, 0x02);
00686 SCVAL(cli->outbuf,smb_ntcreate_SecurityFlags, SecuityFlags);
00687
00688 p = smb_buf(cli->outbuf);
00689
00690 p += clistr_align_out(cli, p, 0);
00691 len = clistr_push(cli, p, fname, -1, 0);
00692 p += len;
00693 SSVAL(cli->outbuf,smb_ntcreate_NameLength, len);
00694
00695 p += clistr_push(cli, p, "", -1, STR_TERMINATE);
00696
00697 cli_setup_bcc(cli, p);
00698
00699 cli_send_smb(cli);
00700 if (!cli_receive_smb(cli)) {
00701 return -1;
00702 }
00703
00704 if (cli_is_error(cli)) {
00705 return -1;
00706 }
00707
00708 return SVAL(cli->inbuf,smb_vwv2 + 1);
00709 }
00710
00711
00712
00713
00714
00715 int cli_nt_create(struct cli_state *cli, const char *fname, uint32 DesiredAccess)
00716 {
00717 return cli_nt_create_full(cli, fname, 0, DesiredAccess, 0,
00718 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0x0, 0x0);
00719 }
00720
00721
00722
00723
00724
00725
00726 int cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode)
00727 {
00728 char *p;
00729 unsigned openfn=0;
00730 unsigned accessmode=0;
00731
00732 if (flags & O_CREAT)
00733 openfn |= (1<<4);
00734 if (!(flags & O_EXCL)) {
00735 if (flags & O_TRUNC)
00736 openfn |= (1<<1);
00737 else
00738 openfn |= (1<<0);
00739 }
00740
00741 accessmode = (share_mode<<4);
00742
00743 if ((flags & O_ACCMODE) == O_RDWR) {
00744 accessmode |= 2;
00745 } else if ((flags & O_ACCMODE) == O_WRONLY) {
00746 accessmode |= 1;
00747 }
00748
00749 #if defined(O_SYNC)
00750 if ((flags & O_SYNC) == O_SYNC) {
00751 accessmode |= (1<<14);
00752 }
00753 #endif
00754
00755 if (share_mode == DENY_FCB) {
00756 accessmode = 0xFF;
00757 }
00758
00759 memset(cli->outbuf,'\0',smb_size);
00760 memset(cli->inbuf,'\0',smb_size);
00761
00762 set_message(cli->outbuf,15,0,True);
00763
00764 SCVAL(cli->outbuf,smb_com,SMBopenX);
00765 SSVAL(cli->outbuf,smb_tid,cli->cnum);
00766 cli_setup_packet(cli);
00767
00768 SSVAL(cli->outbuf,smb_vwv0,0xFF);
00769 SSVAL(cli->outbuf,smb_vwv2,0);
00770 SSVAL(cli->outbuf,smb_vwv3,accessmode);
00771 SSVAL(cli->outbuf,smb_vwv4,aSYSTEM | aHIDDEN);
00772 SSVAL(cli->outbuf,smb_vwv5,0);
00773 SSVAL(cli->outbuf,smb_vwv8,openfn);
00774
00775 if (cli->use_oplocks) {
00776
00777
00778 SCVAL(cli->outbuf,smb_flg, CVAL(cli->outbuf,smb_flg)|
00779 FLAG_REQUEST_OPLOCK|FLAG_REQUEST_BATCH_OPLOCK);
00780 SSVAL(cli->outbuf,smb_vwv2,SVAL(cli->outbuf,smb_vwv2) | 6);
00781 }
00782
00783 p = smb_buf(cli->outbuf);
00784 p += clistr_push(cli, p, fname, -1, STR_TERMINATE);
00785
00786 cli_setup_bcc(cli, p);
00787
00788 cli_send_smb(cli);
00789 if (!cli_receive_smb(cli)) {
00790 return -1;
00791 }
00792
00793 if (cli_is_error(cli)) {
00794 return -1;
00795 }
00796
00797 return SVAL(cli->inbuf,smb_vwv2);
00798 }
00799
00800
00801
00802
00803
00804 BOOL cli_close(struct cli_state *cli, int fnum)
00805 {
00806 memset(cli->outbuf,'\0',smb_size);
00807 memset(cli->inbuf,'\0',smb_size);
00808
00809 set_message(cli->outbuf,3,0,True);
00810
00811 SCVAL(cli->outbuf,smb_com,SMBclose);
00812 SSVAL(cli->outbuf,smb_tid,cli->cnum);
00813 cli_setup_packet(cli);
00814
00815 SSVAL(cli->outbuf,smb_vwv0,fnum);
00816 SIVALS(cli->outbuf,smb_vwv1,-1);
00817
00818 cli_send_smb(cli);
00819 if (!cli_receive_smb(cli)) {
00820 return False;
00821 }
00822
00823 return !cli_is_error(cli);
00824 }
00825
00826
00827
00828
00829
00830
00831
00832 NTSTATUS cli_locktype(struct cli_state *cli, int fnum,
00833 uint32 offset, uint32 len, int timeout, unsigned char locktype)
00834 {
00835 char *p;
00836 int saved_timeout = cli->timeout;
00837
00838 memset(cli->outbuf,'\0',smb_size);
00839 memset(cli->inbuf,'\0', smb_size);
00840
00841 set_message(cli->outbuf,8,0,True);
00842
00843 SCVAL(cli->outbuf,smb_com,SMBlockingX);
00844 SSVAL(cli->outbuf,smb_tid,cli->cnum);
00845 cli_setup_packet(cli);
00846
00847 SCVAL(cli->outbuf,smb_vwv0,0xFF);
00848 SSVAL(cli->outbuf,smb_vwv2,fnum);
00849 SCVAL(cli->outbuf,smb_vwv3,locktype);
00850 SIVALS(cli->outbuf, smb_vwv4, timeout);
00851 SSVAL(cli->outbuf,smb_vwv6,0);
00852 SSVAL(cli->outbuf,smb_vwv7,1);
00853
00854 p = smb_buf(cli->outbuf);
00855 SSVAL(p, 0, cli->pid);
00856 SIVAL(p, 2, offset);
00857 SIVAL(p, 6, len);
00858
00859 p += 10;
00860
00861 cli_setup_bcc(cli, p);
00862
00863 cli_send_smb(cli);
00864
00865 if (timeout != 0) {
00866 cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000);
00867 }
00868
00869 if (!cli_receive_smb(cli)) {
00870 cli->timeout = saved_timeout;
00871 return NT_STATUS_UNSUCCESSFUL;
00872 }
00873
00874 cli->timeout = saved_timeout;
00875
00876 return cli_nt_error(cli);
00877 }
00878
00879
00880
00881
00882
00883
00884 BOOL cli_lock(struct cli_state *cli, int fnum,
00885 uint32 offset, uint32 len, int timeout, enum brl_type lock_type)
00886 {
00887 char *p;
00888 int saved_timeout = cli->timeout;
00889
00890 memset(cli->outbuf,'\0',smb_size);
00891 memset(cli->inbuf,'\0', smb_size);
00892
00893 set_message(cli->outbuf,8,0,True);
00894
00895 SCVAL(cli->outbuf,smb_com,SMBlockingX);
00896 SSVAL(cli->outbuf,smb_tid,cli->cnum);
00897 cli_setup_packet(cli);
00898
00899 SCVAL(cli->outbuf,smb_vwv0,0xFF);
00900 SSVAL(cli->outbuf,smb_vwv2,fnum);
00901 SCVAL(cli->outbuf,smb_vwv3,(lock_type == READ_LOCK? 1 : 0));
00902 SIVALS(cli->outbuf, smb_vwv4, timeout);
00903 SSVAL(cli->outbuf,smb_vwv6,0);
00904 SSVAL(cli->outbuf,smb_vwv7,1);
00905
00906 p = smb_buf(cli->outbuf);
00907 SSVAL(p, 0, cli->pid);
00908 SIVAL(p, 2, offset);
00909 SIVAL(p, 6, len);
00910
00911 p += 10;
00912
00913 cli_setup_bcc(cli, p);
00914
00915 cli_send_smb(cli);
00916
00917 if (timeout != 0) {
00918 cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout*2 + 5*1000);
00919 }
00920
00921 if (!cli_receive_smb(cli)) {
00922 cli->timeout = saved_timeout;
00923 return False;
00924 }
00925
00926 cli->timeout = saved_timeout;
00927
00928 if (cli_is_error(cli)) {
00929 return False;
00930 }
00931
00932 return True;
00933 }
00934
00935
00936
00937
00938
00939 BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len)
00940 {
00941 char *p;
00942
00943 memset(cli->outbuf,'\0',smb_size);
00944 memset(cli->inbuf,'\0',smb_size);
00945
00946 set_message(cli->outbuf,8,0,True);
00947
00948 SCVAL(cli->outbuf,smb_com,SMBlockingX);
00949 SSVAL(cli->outbuf,smb_tid,cli->cnum);
00950 cli_setup_packet(cli);
00951
00952 SCVAL(cli->outbuf,smb_vwv0,0xFF);
00953 SSVAL(cli->outbuf,smb_vwv2,fnum);
00954 SCVAL(cli->outbuf,smb_vwv3,0);
00955 SIVALS(cli->outbuf, smb_vwv4, 0);
00956 SSVAL(cli->outbuf,smb_vwv6,1);
00957 SSVAL(cli->outbuf,smb_vwv7,0);
00958
00959 p = smb_buf(cli->outbuf);
00960 SSVAL(p, 0, cli->pid);
00961 SIVAL(p, 2, offset);
00962 SIVAL(p, 6, len);
00963 p += 10;
00964 cli_setup_bcc(cli, p);
00965 cli_send_smb(cli);
00966 if (!cli_receive_smb(cli)) {
00967 return False;
00968 }
00969
00970 if (cli_is_error(cli)) {
00971 return False;
00972 }
00973
00974 return True;
00975 }
00976
00977
00978
00979
00980
00981 BOOL cli_lock64(struct cli_state *cli, int fnum,
00982 SMB_BIG_UINT offset, SMB_BIG_UINT len, int timeout, enum brl_type lock_type)
00983 {
00984 char *p;
00985 int saved_timeout = cli->timeout;
00986 int ltype;
00987
00988 if (! (cli->capabilities & CAP_LARGE_FILES)) {
00989 return cli_lock(cli, fnum, offset, len, timeout, lock_type);
00990 }
00991
00992 ltype = (lock_type == READ_LOCK? 1 : 0);
00993 ltype |= LOCKING_ANDX_LARGE_FILES;
00994
00995 memset(cli->outbuf,'\0',smb_size);
00996 memset(cli->inbuf,'\0', smb_size);
00997
00998 set_message(cli->outbuf,8,0,True);
00999
01000 SCVAL(cli->outbuf,smb_com,SMBlockingX);
01001 SSVAL(cli->outbuf,smb_tid,cli->cnum);
01002 cli_setup_packet(cli);
01003
01004 SCVAL(cli->outbuf,smb_vwv0,0xFF);
01005 SSVAL(cli->outbuf,smb_vwv2,fnum);
01006 SCVAL(cli->outbuf,smb_vwv3,ltype);
01007 SIVALS(cli->outbuf, smb_vwv4, timeout);
01008 SSVAL(cli->outbuf,smb_vwv6,0);
01009 SSVAL(cli->outbuf,smb_vwv7,1);
01010
01011 p = smb_buf(cli->outbuf);
01012 SIVAL(p, 0, cli->pid);
01013 SOFF_T_R(p, 4, offset);
01014 SOFF_T_R(p, 12, len);
01015 p += 20;
01016
01017 cli_setup_bcc(cli, p);
01018 cli_send_smb(cli);
01019
01020 if (timeout != 0) {
01021 cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 5*1000);
01022 }
01023
01024 if (!cli_receive_smb(cli)) {
01025 cli->timeout = saved_timeout;
01026 return False;
01027 }
01028
01029 cli->timeout = saved_timeout;
01030
01031 if (cli_is_error(cli)) {
01032 return False;
01033 }
01034
01035 return True;
01036 }
01037
01038
01039
01040
01041
01042 BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_UINT len)
01043 {
01044 char *p;
01045
01046 if (! (cli->capabilities & CAP_LARGE_FILES)) {
01047 return cli_unlock(cli, fnum, offset, len);
01048 }
01049
01050 memset(cli->outbuf,'\0',smb_size);
01051 memset(cli->inbuf,'\0',smb_size);
01052
01053 set_message(cli->outbuf,8,0,True);
01054
01055 SCVAL(cli->outbuf,smb_com,SMBlockingX);
01056 SSVAL(cli->outbuf,smb_tid,cli->cnum);
01057 cli_setup_packet(cli);
01058
01059 SCVAL(cli->outbuf,smb_vwv0,0xFF);
01060 SSVAL(cli->outbuf,smb_vwv2,fnum);
01061 SCVAL(cli->outbuf,smb_vwv3,LOCKING_ANDX_LARGE_FILES);
01062 SIVALS(cli->outbuf, smb_vwv4, 0);
01063 SSVAL(cli->outbuf,smb_vwv6,1);
01064 SSVAL(cli->outbuf,smb_vwv7,0);
01065
01066 p = smb_buf(cli->outbuf);
01067 SIVAL(p, 0, cli->pid);
01068 SOFF_T_R(p, 4, offset);
01069 SOFF_T_R(p, 12, len);
01070 p += 20;
01071 cli_setup_bcc(cli, p);
01072 cli_send_smb(cli);
01073 if (!cli_receive_smb(cli)) {
01074 return False;
01075 }
01076
01077 if (cli_is_error(cli)) {
01078 return False;
01079 }
01080
01081 return True;
01082 }
01083
01084
01085
01086
01087
01088 static BOOL cli_posix_lock_internal(struct cli_state *cli, int fnum,
01089 SMB_BIG_UINT offset, SMB_BIG_UINT len, BOOL wait_lock, enum brl_type lock_type)
01090 {
01091 unsigned int param_len = 4;
01092 unsigned int data_len = POSIX_LOCK_DATA_SIZE;
01093 uint16 setup = TRANSACT2_SETFILEINFO;
01094 char param[4];
01095 unsigned char data[POSIX_LOCK_DATA_SIZE];
01096 char *rparam=NULL, *rdata=NULL;
01097 int saved_timeout = cli->timeout;
01098
01099 SSVAL(param,0,fnum);
01100 SSVAL(param,2,SMB_SET_POSIX_LOCK);
01101
01102 switch (lock_type) {
01103 case READ_LOCK:
01104 SSVAL(data, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_READ);
01105 break;
01106 case WRITE_LOCK:
01107 SSVAL(data, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_WRITE);
01108 break;
01109 case UNLOCK_LOCK:
01110 SSVAL(data, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_UNLOCK);
01111 break;
01112 default:
01113 return False;
01114 }
01115
01116 if (wait_lock) {
01117 SSVAL(data, POSIX_LOCK_FLAGS_OFFSET, POSIX_LOCK_FLAG_WAIT);
01118 cli->timeout = 0x7FFFFFFF;
01119 } else {
01120 SSVAL(data, POSIX_LOCK_FLAGS_OFFSET, POSIX_LOCK_FLAG_NOWAIT);
01121 }
01122
01123 SIVAL(data, POSIX_LOCK_PID_OFFSET, cli->pid);
01124 SOFF_T(data, POSIX_LOCK_START_OFFSET, offset);
01125 SOFF_T(data, POSIX_LOCK_LEN_OFFSET, len);
01126
01127 if (!cli_send_trans(cli, SMBtrans2,
01128 NULL,
01129 -1, 0,
01130 &setup, 1, 0,
01131 param, param_len, 2,
01132 (char *)&data, data_len, cli->max_xmit
01133 )) {
01134 cli->timeout = saved_timeout;
01135 return False;
01136 }
01137
01138 if (!cli_receive_trans(cli, SMBtrans2,
01139 &rparam, ¶m_len,
01140 &rdata, &data_len)) {
01141 cli->timeout = saved_timeout;
01142 SAFE_FREE(rdata);
01143 SAFE_FREE(rparam);
01144 return False;
01145 }
01146
01147 cli->timeout = saved_timeout;
01148
01149 SAFE_FREE(rdata);
01150 SAFE_FREE(rparam);
01151
01152 return True;
01153 }
01154
01155
01156
01157
01158
01159 BOOL cli_posix_lock(struct cli_state *cli, int fnum,
01160 SMB_BIG_UINT offset, SMB_BIG_UINT len,
01161 BOOL wait_lock, enum brl_type lock_type)
01162 {
01163 if (lock_type != READ_LOCK && lock_type != WRITE_LOCK) {
01164 return False;
01165 }
01166 return cli_posix_lock_internal(cli, fnum, offset, len, wait_lock, lock_type);
01167 }
01168
01169
01170
01171
01172
01173 BOOL cli_posix_unlock(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_UINT len)
01174 {
01175 return cli_posix_lock_internal(cli, fnum, offset, len, False, UNLOCK_LOCK);
01176 }
01177
01178
01179
01180
01181
01182 BOOL cli_posix_getlock(struct cli_state *cli, int fnum, SMB_BIG_UINT *poffset, SMB_BIG_UINT *plen)
01183 {
01184 return True;
01185 }
01186
01187
01188
01189
01190
01191 BOOL cli_getattrE(struct cli_state *cli, int fd,
01192 uint16 *attr, SMB_OFF_T *size,
01193 time_t *change_time,
01194 time_t *access_time,
01195 time_t *write_time)
01196 {
01197 memset(cli->outbuf,'\0',smb_size);
01198 memset(cli->inbuf,'\0',smb_size);
01199
01200 set_message(cli->outbuf,1,0,True);
01201
01202 SCVAL(cli->outbuf,smb_com,SMBgetattrE);
01203 SSVAL(cli->outbuf,smb_tid,cli->cnum);
01204 cli_setup_packet(cli);
01205
01206 SSVAL(cli->outbuf,smb_vwv0,fd);
01207
01208 cli_send_smb(cli);
01209 if (!cli_receive_smb(cli)) {
01210 return False;
01211 }
01212
01213 if (cli_is_error(cli)) {
01214 return False;
01215 }
01216
01217 if (size) {
01218 *size = IVAL(cli->inbuf, smb_vwv6);
01219 }
01220
01221 if (attr) {
01222 *attr = SVAL(cli->inbuf,smb_vwv10);
01223 }
01224
01225 if (change_time) {
01226 *change_time = cli_make_unix_date2(cli, cli->inbuf+smb_vwv0);
01227 }
01228
01229 if (access_time) {
01230 *access_time = cli_make_unix_date2(cli, cli->inbuf+smb_vwv2);
01231 }
01232
01233 if (write_time) {
01234 *write_time = cli_make_unix_date2(cli, cli->inbuf+smb_vwv4);
01235 }
01236
01237 return True;
01238 }
01239
01240
01241
01242
01243
01244 BOOL cli_getatr(struct cli_state *cli, const char *fname,
01245 uint16 *attr, SMB_OFF_T *size, time_t *write_time)
01246 {
01247 char *p;
01248
01249 memset(cli->outbuf,'\0',smb_size);
01250 memset(cli->inbuf,'\0',smb_size);
01251
01252 set_message(cli->outbuf,0,0,True);
01253
01254 SCVAL(cli->outbuf,smb_com,SMBgetatr);
01255 SSVAL(cli->outbuf,smb_tid,cli->cnum);
01256 cli_setup_packet(cli);
01257
01258 p = smb_buf(cli->outbuf);
01259 *p++ = 4;
01260 p += clistr_push(cli, p, fname, -1, STR_TERMINATE);
01261
01262 cli_setup_bcc(cli, p);
01263
01264 cli_send_smb(cli);
01265 if (!cli_receive_smb(cli)) {
01266 return False;
01267 }
01268
01269 if (cli_is_error(cli)) {
01270 return False;
01271 }
01272
01273 if (size) {
01274 *size = IVAL(cli->inbuf, smb_vwv3);
01275 }
01276
01277 if (write_time) {
01278 *write_time = cli_make_unix_date3(cli, cli->inbuf+smb_vwv1);
01279 }
01280
01281 if (attr) {
01282 *attr = SVAL(cli->inbuf,smb_vwv0);
01283 }
01284
01285
01286 return True;
01287 }
01288
01289
01290
01291
01292
01293 BOOL cli_setattrE(struct cli_state *cli, int fd,
01294 time_t change_time,
01295 time_t access_time,
01296 time_t write_time)
01297
01298 {
01299 char *p;
01300
01301 memset(cli->outbuf,'\0',smb_size);
01302 memset(cli->inbuf,'\0',smb_size);
01303
01304 set_message(cli->outbuf,7,0,True);
01305
01306 SCVAL(cli->outbuf,smb_com,SMBsetattrE);
01307 SSVAL(cli->outbuf,smb_tid,cli->cnum);
01308 cli_setup_packet(cli);
01309
01310 SSVAL(cli->outbuf,smb_vwv0, fd);
01311 cli_put_dos_date2(cli, cli->outbuf,smb_vwv1, change_time);
01312 cli_put_dos_date2(cli, cli->outbuf,smb_vwv3, access_time);
01313 cli_put_dos_date2(cli, cli->outbuf,smb_vwv5, write_time);
01314
01315 p = smb_buf(cli->outbuf);
01316 *p++ = 4;
01317
01318 cli_setup_bcc(cli, p);
01319
01320 cli_send_smb(cli);
01321 if (!cli_receive_smb(cli)) {
01322 return False;
01323 }
01324
01325 if (cli_is_error(cli)) {
01326 return False;
01327 }
01328
01329 return True;
01330 }
01331
01332
01333
01334
01335
01336 BOOL cli_setatr(struct cli_state *cli, const char *fname, uint16 attr, time_t t)
01337 {
01338 char *p;
01339
01340 memset(cli->outbuf,'\0',smb_size);
01341 memset(cli->inbuf,'\0',smb_size);
01342
01343 set_message(cli->outbuf,8,0,True);
01344
01345 SCVAL(cli->outbuf,smb_com,SMBsetatr);
01346 SSVAL(cli->outbuf,smb_tid,cli->cnum);
01347 cli_setup_packet(cli);
01348
01349 SSVAL(cli->outbuf,smb_vwv0, attr);
01350 cli_put_dos_date3(cli, cli->outbuf,smb_vwv1, t);
01351
01352 p = smb_buf(cli->outbuf);
01353 *p++ = 4;
01354 p += clistr_push(cli, p, fname, -1, STR_TERMINATE);
01355 *p++ = 4;
01356
01357 cli_setup_bcc(cli, p);
01358
01359 cli_send_smb(cli);
01360 if (!cli_receive_smb(cli)) {
01361 return False;
01362 }
01363
01364 if (cli_is_error(cli)) {
01365 return False;
01366 }
01367
01368 return True;
01369 }
01370
01371
01372
01373
01374 BOOL cli_chkpath(struct cli_state *cli, const char *path)
01375 {
01376 pstring path2;
01377 char *p;
01378
01379 pstrcpy(path2,path);
01380 trim_char(path2,'\0','\\');
01381 if (!*path2)
01382 *path2 = '\\';
01383
01384 memset(cli->outbuf,'\0',smb_size);
01385 set_message(cli->outbuf,0,0,True);
01386 SCVAL(cli->outbuf,smb_com,SMBcheckpath);
01387 SSVAL(cli->outbuf,smb_tid,cli->cnum);
01388 cli_setup_packet(cli);
01389 p = smb_buf(cli->outbuf);
01390 *p++ = 4;
01391 p += clistr_push(cli, p, path2, -1, STR_TERMINATE);
01392
01393 cli_setup_bcc(cli, p);
01394
01395 cli_send_smb(cli);
01396 if (!cli_receive_smb(cli)) {
01397 return False;
01398 }
01399
01400 if (cli_is_error(cli)) return False;
01401
01402 return True;
01403 }
01404
01405
01406
01407
01408
01409 BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail)
01410 {
01411 memset(cli->outbuf,'\0',smb_size);
01412 set_message(cli->outbuf,0,0,True);
01413 SCVAL(cli->outbuf,smb_com,SMBdskattr);
01414 SSVAL(cli->outbuf,smb_tid,cli->cnum);
01415 cli_setup_packet(cli);
01416
01417 cli_send_smb(cli);
01418 if (!cli_receive_smb(cli)) {
01419 return False;
01420 }
01421
01422 *bsize = SVAL(cli->inbuf,smb_vwv1)*SVAL(cli->inbuf,smb_vwv2);
01423 *total = SVAL(cli->inbuf,smb_vwv0);
01424 *avail = SVAL(cli->inbuf,smb_vwv3);
01425
01426 return True;
01427 }
01428
01429
01430
01431
01432
01433 int cli_ctemp(struct cli_state *cli, const char *path, char **tmp_path)
01434 {
01435 int len;
01436 char *p;
01437
01438 memset(cli->outbuf,'\0',smb_size);
01439 memset(cli->inbuf,'\0',smb_size);
01440
01441 set_message(cli->outbuf,3,0,True);
01442
01443 SCVAL(cli->outbuf,smb_com,SMBctemp);
01444 SSVAL(cli->outbuf,smb_tid,cli->cnum);
01445 cli_setup_packet(cli);
01446
01447 SSVAL(cli->outbuf,smb_vwv0,0);
01448 SIVALS(cli->outbuf,smb_vwv1,-1);
01449
01450 p = smb_buf(cli->outbuf);
01451 *p++ = 4;
01452 p += clistr_push(cli, p, path, -1, STR_TERMINATE);
01453
01454 cli_setup_bcc(cli, p);
01455
01456 cli_send_smb(cli);
01457 if (!cli_receive_smb(cli)) {
01458 return -1;
01459 }
01460
01461 if (cli_is_error(cli)) {
01462 return -1;
01463 }
01464
01465
01466
01467 p = smb_buf(cli->inbuf);
01468 p += 4;
01469 len = smb_buflen(cli->inbuf) - 4;
01470 if (len <= 0) return -1;
01471
01472 if (tmp_path) {
01473 pstring path2;
01474 clistr_pull(cli, path2, p,
01475 sizeof(path2), len, STR_ASCII);
01476 *tmp_path = SMB_STRDUP(path2);
01477 }
01478
01479 return SVAL(cli->inbuf,smb_vwv0);
01480 }
01481
01482
01483
01484
01485
01486 NTSTATUS cli_raw_ioctl(struct cli_state *cli, int fnum, uint32 code, DATA_BLOB *blob)
01487 {
01488 memset(cli->outbuf,'\0',smb_size);
01489 memset(cli->inbuf,'\0',smb_size);
01490
01491 set_message(cli->outbuf, 3, 0, True);
01492 SCVAL(cli->outbuf,smb_com,SMBioctl);
01493 cli_setup_packet(cli);
01494
01495 SSVAL(cli->outbuf, smb_vwv0, fnum);
01496 SSVAL(cli->outbuf, smb_vwv1, code>>16);
01497 SSVAL(cli->outbuf, smb_vwv2, (code&0xFFFF));
01498
01499 cli_send_smb(cli);
01500 if (!cli_receive_smb(cli)) {
01501 return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
01502 }
01503
01504 if (cli_is_error(cli)) {
01505 return cli_nt_error(cli);
01506 }
01507
01508 *blob = data_blob(NULL, 0);
01509
01510 return NT_STATUS_OK;
01511 }
01512
01513
01514
01515
01516
01517 static BOOL cli_set_ea(struct cli_state *cli, uint16 setup, char *param, unsigned int param_len,
01518 const char *ea_name, const char *ea_val, size_t ea_len)
01519 {
01520 unsigned int data_len = 0;
01521 char *data = NULL;
01522 char *rparam=NULL, *rdata=NULL;
01523 char *p;
01524 size_t ea_namelen = strlen(ea_name);
01525
01526 if (ea_namelen == 0 && ea_len == 0) {
01527 data_len = 4;
01528 data = (char *)SMB_MALLOC(data_len);
01529 if (!data) {
01530 return False;
01531 }
01532 p = data;
01533 SIVAL(p,0,data_len);
01534 } else {
01535 data_len = 4 + 4 + ea_namelen + 1 + ea_len;
01536 data = (char *)SMB_MALLOC(data_len);
01537 if (!data) {
01538 return False;
01539 }
01540 p = data;
01541 SIVAL(p,0,data_len);
01542 p += 4;
01543 SCVAL(p, 0, 0);
01544 SCVAL(p, 1, ea_namelen);
01545 SSVAL(p, 2, ea_len);
01546 memcpy(p+4, ea_name, ea_namelen+1);
01547 memcpy(p+4+ea_namelen+1, ea_val, ea_len);
01548 }
01549
01550 if (!cli_send_trans(cli, SMBtrans2,
01551 NULL,
01552 -1, 0,
01553 &setup, 1, 0,
01554 param, param_len, 2,
01555 data, data_len, cli->max_xmit
01556 )) {
01557 return False;
01558 }
01559
01560 if (!cli_receive_trans(cli, SMBtrans2,
01561 &rparam, ¶m_len,
01562 &rdata, &data_len)) {
01563 return False;
01564 }
01565
01566 SAFE_FREE(data);
01567 SAFE_FREE(rdata);
01568 SAFE_FREE(rparam);
01569
01570 return True;
01571 }
01572
01573
01574
01575
01576
01577 BOOL cli_set_ea_path(struct cli_state *cli, const char *path, const char *ea_name, const char *ea_val, size_t ea_len)
01578 {
01579 uint16 setup = TRANSACT2_SETPATHINFO;
01580 unsigned int param_len = 0;
01581 char param[sizeof(pstring)+6];
01582 size_t srclen = 2*(strlen(path)+1);
01583 char *p;
01584
01585 memset(param, 0, sizeof(param));
01586 SSVAL(param,0,SMB_INFO_SET_EA);
01587 p = ¶m[6];
01588
01589 p += clistr_push(cli, p, path, MIN(srclen, sizeof(param)-6), STR_TERMINATE);
01590 param_len = PTR_DIFF(p, param);
01591
01592 return cli_set_ea(cli, setup, param, param_len, ea_name, ea_val, ea_len);
01593 }
01594
01595
01596
01597
01598
01599 BOOL cli_set_ea_fnum(struct cli_state *cli, int fnum, const char *ea_name, const char *ea_val, size_t ea_len)
01600 {
01601 char param[6];
01602 uint16 setup = TRANSACT2_SETFILEINFO;
01603
01604 memset(param, 0, 6);
01605 SSVAL(param,0,fnum);
01606 SSVAL(param,2,SMB_INFO_SET_EA);
01607
01608 return cli_set_ea(cli, setup, param, 6, ea_name, ea_val, ea_len);
01609 }
01610
01611
01612
01613
01614
01615 static BOOL cli_get_ea_list(struct cli_state *cli,
01616 uint16 setup, char *param, unsigned int param_len,
01617 TALLOC_CTX *ctx,
01618 size_t *pnum_eas,
01619 struct ea_struct **pea_list)
01620 {
01621 unsigned int data_len = 0;
01622 unsigned int rparam_len, rdata_len;
01623 char *rparam=NULL, *rdata=NULL;
01624 char *p;
01625 size_t ea_size;
01626 size_t num_eas;
01627 BOOL ret = False;
01628 struct ea_struct *ea_list;
01629
01630 *pnum_eas = 0;
01631 if (pea_list) {
01632 *pea_list = NULL;
01633 }
01634
01635 if (!cli_send_trans(cli, SMBtrans2,
01636 NULL,
01637 -1, 0,
01638 &setup, 1, 0,
01639 param, param_len, 10,
01640 NULL, data_len, cli->max_xmit
01641 )) {
01642 return False;
01643 }
01644
01645 if (!cli_receive_trans(cli, SMBtrans2,
01646 &rparam, &rparam_len,
01647 &rdata, &rdata_len)) {
01648 return False;
01649 }
01650
01651 if (!rdata || rdata_len < 4) {
01652 goto out;
01653 }
01654
01655 ea_size = (size_t)IVAL(rdata,0);
01656 if (ea_size > rdata_len) {
01657 goto out;
01658 }
01659
01660 if (ea_size == 0) {
01661
01662 ret = True;
01663 goto out;
01664 }
01665
01666 p = rdata + 4;
01667 ea_size -= 4;
01668
01669
01670 for (num_eas = 0; ea_size >= 4; num_eas++) {
01671 unsigned int ea_namelen = CVAL(p,1);
01672 unsigned int ea_valuelen = SVAL(p,2);
01673 if (ea_namelen == 0) {
01674 goto out;
01675 }
01676 if (4 + ea_namelen + 1 + ea_valuelen > ea_size) {
01677 goto out;
01678 }
01679 ea_size -= 4 + ea_namelen + 1 + ea_valuelen;
01680 p += 4 + ea_namelen + 1 + ea_valuelen;
01681 }
01682
01683 if (num_eas == 0) {
01684 ret = True;
01685 goto out;
01686 }
01687
01688 *pnum_eas = num_eas;
01689 if (!pea_list) {
01690
01691 ret = True;
01692 goto out;
01693 }
01694
01695 ea_list = TALLOC_ARRAY(ctx, struct ea_struct, num_eas);
01696 if (!ea_list) {
01697 goto out;
01698 }
01699
01700 ea_size = (size_t)IVAL(rdata,0);
01701 p = rdata + 4;
01702
01703 for (num_eas = 0; num_eas < *pnum_eas; num_eas++ ) {
01704 struct ea_struct *ea = &ea_list[num_eas];
01705 fstring unix_ea_name;
01706 unsigned int ea_namelen = CVAL(p,1);
01707 unsigned int ea_valuelen = SVAL(p,2);
01708
01709 ea->flags = CVAL(p,0);
01710 unix_ea_name[0] = '\0';
01711 pull_ascii_fstring(unix_ea_name, p + 4);
01712 ea->name = talloc_strdup(ctx, unix_ea_name);
01713
01714 ea->value = data_blob_talloc(ctx, NULL, ea_valuelen + 1);
01715 if (!ea->value.data) {
01716 goto out;
01717 }
01718 if (ea_valuelen) {
01719 memcpy(ea->value.data, p+4+ea_namelen+1, ea_valuelen);
01720 }
01721 ea->value.data[ea_valuelen] = 0;
01722 ea->value.length--;
01723 p += 4 + ea_namelen + 1 + ea_valuelen;
01724 }
01725
01726 *pea_list = ea_list;
01727 ret = True;
01728
01729 out :
01730
01731 SAFE_FREE(rdata);
01732 SAFE_FREE(rparam);
01733 return ret;
01734 }
01735
01736
01737
01738
01739
01740 BOOL cli_get_ea_list_path(struct cli_state *cli, const char *path,
01741 TALLOC_CTX *ctx,
01742 size_t *pnum_eas,
01743 struct ea_struct **pea_list)
01744 {
01745 uint16 setup = TRANSACT2_QPATHINFO;
01746 unsigned int param_len = 0;
01747 char param[sizeof(pstring)+6];
01748 char *p;
01749
01750 p = param;
01751 memset(p, 0, 6);
01752 SSVAL(p, 0, SMB_INFO_QUERY_ALL_EAS);
01753 p += 6;
01754 p += clistr_push(cli, p, path, sizeof(pstring)-6, STR_TERMINATE);
01755 param_len = PTR_DIFF(p, param);
01756
01757 return cli_get_ea_list(cli, setup, param, param_len, ctx, pnum_eas, pea_list);
01758 }
01759
01760
01761
01762
01763
01764 BOOL cli_get_ea_list_fnum(struct cli_state *cli, int fnum,
01765 TALLOC_CTX *ctx,
01766 size_t *pnum_eas,
01767 struct ea_struct **pea_list)
01768 {
01769 uint16 setup = TRANSACT2_QFILEINFO;
01770 char param[6];
01771
01772 memset(param, 0, 6);
01773 SSVAL(param,0,fnum);
01774 SSVAL(param,2,SMB_INFO_SET_EA);
01775
01776 return cli_get_ea_list(cli, setup, param, 6, ctx, pnum_eas, pea_list);
01777 }
01778
01779
01780
01781
01782
01783 static uint32 open_flags_to_wire(int flags)
01784 {
01785 int open_mode = flags & O_ACCMODE;
01786 uint32 ret = 0;
01787
01788 switch (open_mode) {
01789 case O_WRONLY:
01790 ret |= SMB_O_WRONLY;
01791 break;
01792 case O_RDWR:
01793 ret |= SMB_O_RDWR;
01794 break;
01795 default:
01796 case O_RDONLY:
01797 ret |= SMB_O_RDONLY;
01798 break;
01799 }
01800
01801 if (flags & O_CREAT) {
01802 ret |= SMB_O_CREAT;
01803 }
01804 if (flags & O_EXCL) {
01805 ret |= SMB_O_EXCL;
01806 }
01807 if (flags & O_TRUNC) {
01808 ret |= SMB_O_TRUNC;
01809 }
01810 #if defined(O_SYNC)
01811 if (flags & O_SYNC) {
01812 ret |= SMB_O_SYNC;
01813 }
01814 #endif
01815 if (flags & O_APPEND) {
01816 ret |= SMB_O_APPEND;
01817 }
01818 #if defined(O_DIRECT)
01819 if (flags & O_DIRECT) {
01820 ret |= SMB_O_DIRECT;
01821 }
01822 #endif
01823 #if defined(O_DIRECTORY)
01824 if (flags & O_DIRECTORY) {
01825 ret &= ~(SMB_O_RDONLY|SMB_O_RDWR|SMB_O_WRONLY);
01826 ret |= SMB_O_DIRECTORY;
01827 }
01828 #endif
01829 return ret;
01830 }
01831
01832
01833
01834
01835
01836 static int cli_posix_open_internal(struct cli_state *cli, const char *fname, int flags, mode_t mode, BOOL is_dir)
01837 {
01838 unsigned int data_len = 0;
01839 unsigned int param_len = 0;
01840 uint16 setup = TRANSACT2_SETPATHINFO;
01841 char param[sizeof(pstring)+6];
01842 char data[18];
01843 char *rparam=NULL, *rdata=NULL;
01844 char *p;
01845 int fnum = -1;
01846 uint32 wire_flags = open_flags_to_wire(flags);
01847
01848 memset(param, 0, sizeof(param));
01849 SSVAL(param,0, SMB_POSIX_PATH_OPEN);
01850 p = ¶m[6];
01851
01852 p += clistr_push(cli, p, fname, sizeof(param)-6, STR_TERMINATE);
01853 param_len = PTR_DIFF(p, param);
01854
01855 if (is_dir) {
01856 wire_flags &= ~(SMB_O_RDONLY|SMB_O_RDWR|SMB_O_WRONLY);
01857 wire_flags |= SMB_O_DIRECTORY;
01858 }
01859
01860 p = data;
01861 SIVAL(p,0,0);
01862 SIVAL(p,4,wire_flags);
01863 SIVAL(p,8,unix_perms_to_wire(mode));
01864 SIVAL(p,12,0);
01865 SSVAL(p,16,SMB_NO_INFO_LEVEL_RETURNED);
01866
01867 data_len = 18;
01868
01869 if (!cli_send_trans(cli, SMBtrans2,
01870 NULL,
01871 -1, 0,
01872 &setup, 1, 0,
01873 param, param_len, 2,
01874 (char *)&data, data_len, cli->max_xmit
01875 )) {
01876 return -1;
01877 }
01878
01879 if (!cli_receive_trans(cli, SMBtrans2,
01880 &rparam, ¶m_len,
01881 &rdata, &data_len)) {
01882 return -1;
01883 }
01884
01885 fnum = SVAL(rdata,2);
01886
01887 SAFE_FREE(rdata);
01888 SAFE_FREE(rparam);
01889
01890 return fnum;
01891 }
01892
01893
01894
01895
01896
01897 int cli_posix_open(struct cli_state *cli, const char *fname, int flags, mode_t mode)
01898 {
01899 return cli_posix_open_internal(cli, fname, flags, mode, False);
01900 }
01901
01902
01903
01904
01905
01906 int cli_posix_mkdir(struct cli_state *cli, const char *fname, mode_t mode)
01907 {
01908 return (cli_posix_open_internal(cli, fname, O_CREAT, mode, True) == -1) ? -1 : 0;
01909 }
01910
01911
01912
01913
01914
01915 static BOOL cli_posix_unlink_internal(struct cli_state *cli, const char *fname, BOOL is_dir)
01916 {
01917 unsigned int data_len = 0;
01918 unsigned int param_len = 0;
01919 uint16 setup = TRANSACT2_SETPATHINFO;
01920 char param[sizeof(pstring)+6];
01921 char data[2];
01922 char *rparam=NULL, *rdata=NULL;
01923 char *p;
01924
01925 memset(param, 0, sizeof(param));
01926 SSVAL(param,0, SMB_POSIX_PATH_UNLINK);
01927 p = ¶m[6];
01928
01929 p += clistr_push(cli, p, fname, sizeof(param)-6, STR_TERMINATE);
01930 param_len = PTR_DIFF(p, param);
01931
01932 SSVAL(data, 0, is_dir ? SMB_POSIX_UNLINK_DIRECTORY_TARGET :
01933 SMB_POSIX_UNLINK_FILE_TARGET);
01934 data_len = 2;
01935
01936 if (!cli_send_trans(cli, SMBtrans2,
01937 NULL,
01938 -1, 0,
01939 &setup, 1, 0,
01940 param, param_len, 2,
01941 (char *)&data, data_len, cli->max_xmit
01942 )) {
01943 return False;
01944 }
01945
01946 if (!cli_receive_trans(cli, SMBtrans2,
01947 &rparam, ¶m_len,
01948 &rdata, &data_len)) {
01949 return False;
01950 }
01951
01952 SAFE_FREE(rdata);
01953 SAFE_FREE(rparam);
01954
01955 return True;
01956 }
01957
01958
01959
01960
01961
01962 BOOL cli_posix_unlink(struct cli_state *cli, const char *fname)
01963 {
01964 return cli_posix_unlink_internal(cli, fname, False);
01965 }
01966
01967
01968
01969
01970
01971 int cli_posix_rmdir(struct cli_state *cli, const char *fname)
01972 {
01973 return cli_posix_unlink_internal(cli, fname, True);
01974 }