Changeset 959 for trunk/client/src/smbwrp.c
- Timestamp:
- Aug 16, 2016, 5:35:07 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/client/src/smbwrp.c
r957 r959 34 34 int os2cli_errno(cli_state * cli) 35 35 { 36 if (cli->fd == -1) 37 { 38 return maperror( ENOTCONN); 39 } 40 return maperror(cli_errno(cli)); 36 if (cli->fd == -1) 37 return maperror(ENOTCONN); 38 39 return maperror(cli_errno(cli)); 41 40 } 42 41 43 42 void smbwrp_Logging() 44 43 { 45 46 47 48 49 50 51 52 53 54 55 { 56 strncpy(slogfile, slogfilename, sizeof(slogfile) -1); 57 } 58 59 // init samba for debug messages 60 setup_logging("ndpsmb", DEBUG_FILE);61 lp_set_logfile(slogfile);62 lp_set_cmdline("log level", "10"); 63 reopen_logs();64 65 } 44 char slogfile[_MAX_PATH +1] = {0}; 45 char slogfilename[] = "log.smbc"; 46 char *env = getenv("LOGFILES"); 47 if (env != NULL) 48 { 49 strncpy(slogfile, env, sizeof(slogfile) -1); 50 strncat(slogfile, "\\", sizeof(slogfile) - strlen(slogfile) -1); 51 strncat(slogfile, slogfilename, sizeof(slogfile) - strlen(slogfile) -1); 52 } 53 else 54 strncpy(slogfile, slogfilename, sizeof(slogfile) -1); 55 56 // init samba for debug messages 57 setup_logging("ndpsmb", DEBUG_FILE); 58 lp_set_logfile(slogfile); 59 lp_set_cmdline("log level", "10"); 60 reopen_logs(); 61 62 return; 63 } 64 66 65 const char * smbwrp_getVersion() 67 66 { 68 67 return samba_version_string(); 69 68 } 70 69 71 70 int _System smbwrp_getclisize(void) 72 71 { 73 74 } 75 76 /* ****************************************************77 initialise structures78 *******************************************************/72 return sizeof(struct cli_state); 73 } 74 75 /* 76 * initialise structures 77 */ 79 78 int _System smbwrp_init(void) 80 79 { 81 static int initialised = 0; 82 char *p; 83 84 if (initialised) 85 { 86 return 0; 87 } 88 initialised = 1; 89 90 lp_set_in_client(true); /* Make sure that we tell lp_load we are client */ 91 92 load_case_tables(); 93 94 if (!lp_load(get_dyn_CONFIGFILE(),true,false,false,true)) { 95 debuglocal(0,("The initial smb.conf is missing, defaults are used!\n")); 96 } 97 98 load_interfaces(); 99 100 if (!init_names()) 101 { 102 return 1; 103 } 104 105 if (writeLog()) 106 { 107 smbwrp_Logging(); 108 } 109 110 /* 111 if ((p=smbw_getshared("RESOLVE_ORDER"))) { 112 lp_set_name_resolve_order(p); 113 } 114 */ 115 return 0; 80 static int initialised = 0; 81 char *p; 82 83 if (initialised) 84 return 0; 85 86 initialised = 1; 87 88 lp_set_in_client(true); // Make sure that we tell lp_load we are client 89 90 load_case_tables(); 91 92 if (!lp_load(get_dyn_CONFIGFILE(),true,false,false,true)) 93 debuglocal(0,("The initial smb.conf is missing, defaults are used!\n")); 94 95 load_interfaces(); 96 97 if (!init_names()) 98 return 1; 99 100 if (writeLog()) 101 smbwrp_Logging(); 102 103 /* 104 if ((p=smbw_getshared("RESOLVE_ORDER"))) 105 lp_set_name_resolve_order(p); 106 */ 107 return 0; 116 108 117 109 } … … 119 111 void smbwrp_initthread(void) 120 112 { 121 122 123 124 125 113 /* 114 * Block SIGPIPE (from lib/util_sock.c: write()) 115 * It is not needed and should not stop execution 116 */ 117 BlockSignals(True, SIGPIPE); 126 118 } 127 119 128 120 #if 0 129 /* ****************************************************130 remove redundent stuff from a filename131 *******************************************************/121 /* 122 * remove redundent stuff from a filename 123 */ 132 124 void clean_fname(char *name) 133 125 { 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 if (p2[0] == '/') break; 168 } 169 while (*p2) { 170 p2[0] = p2[3]; 171 p2++;172 } 173 174 175 if (strcmp(name,"/..")==0) { 176 modified = 1; 177 name[1] = 0;178 } 179 180 l = strlen(name); 181 p = l>=3?(name+l-3):name;182 if (strcmp(p,"/..")==0) { 183 modified = 1; 184 for (p2=p-1;p2>name;p2--) { 185 if (p2[0] == '/') break; 186 } 187 if (p2==name) { 188 p[0] = '/'; 189 p[1] = 0; 190 } else { 191 p2[0] = 0;192 } 193 } 194 195 l = strlen(name); 196 p = l>=2?(name+l-2):name;197 if (strcmp(p,"/.")==0) { 198 if (p == name) {199 p[1] = 0; 200 } else { 201 p[0] = 0; 202 } 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 126 char *p, *p2; 127 int l; 128 int modified = 1; 129 130 if (!name) return; 131 132 while (modified) { 133 modified = 0; 134 135 if ((p=strstr(name,"/./"))) { 136 modified = 1; 137 while (*p) { 138 p[0] = p[2]; 139 p++; 140 } 141 } 142 143 if ((p=strstr(name,"//"))) { 144 modified = 1; 145 while (*p) { 146 p[0] = p[1]; 147 p++; 148 } 149 } 150 151 if (strcmp(name,"/../")==0) { 152 modified = 1; 153 name[1] = 0; 154 } 155 156 if ((p=strstr(name,"/../"))) { 157 modified = 1; 158 for (p2=(p>name?p-1:p);p2>name;p2--) { 159 if (p2[0] == '/') 160 break; 161 } 162 while (*p2) { 163 p2[0] = p2[3]; 164 p2++; 165 } 166 } 167 168 if (strcmp(name,"/..")==0) { 169 modified = 1; 170 name[1] = 0; 171 } 172 173 l = strlen(name); 174 p = l >= 3 ? (name+l-3):name; 175 if (strcmp(p,"/..")==0) { 176 modified = 1; 177 for (p2=p-1;p2>name;p2--) { 178 if (p2[0] == '/') 179 break; 180 } 181 if (p2==name) { 182 p[0] = '/'; 183 p[1] = 0; 184 } else 185 p2[0] = 0; 186 } 187 188 l = strlen(name); 189 p = l >= 2 ? (name+l-2):name; 190 if (strcmp(p,"/.")==0) { 191 if (p == name) 192 p[1] = 0; 193 else 194 p[0] = 0; 195 } 196 197 if (strncmp(p=name,"./",2) == 0) { 198 modified = 1; 199 do { 200 p[0] = p[2]; 201 } while (*p++); 202 } 203 204 l = strlen(p=name); 205 if (l > 1 && p[l-1] == '/') { 206 modified = 1; 207 p[l-1] = 0; 208 } 209 } 218 210 } 219 211 #endif 220 212 221 /* ****************************************************222 return a connection to a server223 *******************************************************/213 /* 214 * return a connection to a server 215 */ 224 216 int _System smbwrp_connect( Resource* pRes, cli_state ** cli) 225 217 { 226 smbwrp_server * srv = &pRes->srv; 227 char * server = srv->server_name; 228 char * share = *(srv->share_name) ? srv->share_name : "IPC$"; 229 char * workgroup = srv->workgroup; 230 struct nmb_name called, calling; 231 char *p, *server_n = server; 232 fstring group; 233 struct sockaddr_storage ss; 234 struct cli_state * c; 235 char* dev_type; 236 int loginerror = 0; 237 NTSTATUS status; 238 239 zero_sockaddr(&ss); 240 241 debuglocal(1,"Connecting to \\\\%s:*********@%s:%s\\%s. Master %s:%d\n", srv->username, workgroup, server, share, srv->master, srv->ifmastergroup); 242 243 if (!*server) { 244 struct sockaddr_storage sip; 245 246 if (*workgroup) 247 { 248 if (!find_master_ip(workgroup, &sip)) { 249 return 1; 250 } 251 fstrcpy(group, inet_ntoa(sip.sin_addr)); 252 server_n = group; 253 } else 254 if (*srv->master) 255 { 256 if (srv->ifmastergroup) 257 { 258 if (!find_master_ip(srv->master, &sip)) { 259 return 11; 260 } 261 strncpy(srv->master, inet_ntoa(sip.sin_addr), sizeof(srv->master) - 1); 262 srv->ifmastergroup = 0; 263 } 264 server_n = srv->master; 265 } else 266 { 267 return 10; 268 } 269 } 270 271 make_nmb_name(&calling, global_myname(), 0x0); 272 // make_nmb_name(&calling, "WORK", 0x0); // this machine name 273 make_nmb_name(&called , server_n, 0x20); 218 smbwrp_server * srv = &pRes->srv; 219 char * server = srv->server_name; 220 char * share = *(srv->share_name) ? srv->share_name : "IPC$"; 221 char * workgroup = srv->workgroup; 222 struct nmb_name called, calling; 223 char *p, *server_n = server; 224 fstring group; 225 struct sockaddr_storage ss; 226 struct cli_state * c; 227 char* dev_type; 228 int loginerror = 0; 229 NTSTATUS status; 230 231 zero_sockaddr(&ss); 232 233 debuglocal(1,"Connecting to \\\\%s:*********@%s:%s\\%s. Master %s:%d\n", srv->username, workgroup, server, share, srv->master, srv->ifmastergroup); 234 235 if (!*server) { 236 struct sockaddr_storage sip; 237 238 if (*workgroup) 239 { 240 if (!find_master_ip(workgroup, &sip)) 241 return 1; 242 243 fstrcpy(group, inet_ntoa(sip.sin_addr)); 244 server_n = group; 245 } else if (*srv->master) 246 { 247 if (srv->ifmastergroup) 248 { 249 if (!find_master_ip(srv->master, &sip)) 250 return 11; 251 252 strncpy(srv->master, inet_ntoa(sip.sin_addr), sizeof(srv->master) - 1); 253 srv->ifmastergroup = 0; 254 } 255 server_n = srv->master; 256 } else 257 return 10; 258 } 259 260 make_nmb_name(&calling, global_myname(), 0x0); 261 //make_nmb_name(&calling, "WORK", 0x0); // this machine name 262 make_nmb_name(&called , server_n, 0x20); 274 263 275 264 again: 276 zero_sockaddr(&ss); 277 278 /* have to open a new connection */ 279 if (!(c=cli_initialise())) 280 { 281 return 2; 282 } 283 284 cli_set_timeout(c, 10000); /* 10 seconds. */ 285 286 if (pRes->krb5support == 1) 287 { 288 debuglocal(1,"Kerberos support enabled\n"); 289 c->use_kerberos = True; 290 } 291 292 if (!NT_STATUS_IS_OK(cli_connect(c, server_n, &ss))) 293 { 294 return 3; 295 } 296 297 if (!cli_session_request(c, &calling, &called)) { 298 cli_shutdown(c); 299 if (strcmp(called.name, "*SMBSERVER")) { 300 make_nmb_name(&called , "*SMBSERVER", 0x20); 301 goto again; 302 } 303 return 4; 304 } 305 306 debuglocal(4," session request ok\n"); 307 308 if (!NT_STATUS_IS_OK(cli_negprot(c))) { 309 cli_shutdown(c); 310 return 5; 311 } 312 313 debuglocal(4," session setuping for <%s>/<********> in <%s> %08x %08x %08x\n", srv->username, workgroup, c->protocol, c->sec_mode, c->capabilities); 314 315 if (!NT_STATUS_IS_OK(cli_session_setup(c, srv->username, 316 srv->password, strlen(srv->password), 317 srv->password, strlen(srv->password), 318 workgroup))) { 319 debuglocal(4,"%s/******** login failed\n", srv->username); 320 loginerror = 1; // save the login error 321 322 /* try an anonymous login if it failed */ 323 if (!NT_STATUS_IS_OK(cli_session_setup(c, "", "", 0,"", 0, workgroup))) { 324 debuglocal(4,"Anonymous login failed\n"); 325 cli_shutdown(c); 326 return 6; 327 } 328 debuglocal(4,"Anonymous login successful\n"); 329 status = cli_init_creds(c, "", lp_workgroup(), ""); 330 } else { 331 status = cli_init_creds(c, srv->username, workgroup, srv->password); 332 } 333 334 if (!NT_STATUS_IS_OK(status)) { 335 debuglocal(4,"cli_init_creds() failed\n"); 336 cli_shutdown(c); 337 // if loginerror is != 0 means normal login failed, but anonymous login worked 338 if (loginerror !=0) 339 return 6; 340 else 341 return 7; 342 } 343 344 debuglocal(4," session setup ok. Sending tconx <%s> <********>\n", share); 345 346 // YD ticket:58 we need to check resource type to avoid connecting to printers. 347 // dev type is set to IPC for IPC$, A: for everything else (printers use LPT1:) 348 if (!strcmp( share, "IPC$")) 349 dev_type = "IPC"; 350 else 351 dev_type = "A:"; 352 353 if (!NT_STATUS_IS_OK(cli_tcon_andx(c, share, dev_type, 354 srv->password, strlen(srv->password)+1))) { 355 cli_shutdown(c); 356 // if loginerror is != 0 means normal login failed, but anonymous login worked 357 if (loginerror !=0) 358 return 6; 359 else 360 return 7; 361 } 362 363 debuglocal(4," tconx ok. cli caps %08x\n", c->capabilities); 265 zero_sockaddr(&ss); 266 267 // have to open a new connection 268 if (!(c=cli_initialise())) 269 return 2; 270 271 cli_set_timeout(c, 10000); // 10 seconds 272 273 if (pRes->krb5support == 1) 274 { 275 debuglocal(1,"Kerberos support enabled\n"); 276 c->use_kerberos = True; 277 } 278 279 if (!NT_STATUS_IS_OK(cli_connect(c, server_n, &ss))) 280 return 3; 281 282 if (!cli_session_request(c, &calling, &called)) { 283 cli_shutdown(c); 284 if (strcmp(called.name, "*SMBSERVER")) { 285 make_nmb_name(&called , "*SMBSERVER", 0x20); 286 goto again; 287 } 288 return 4; 289 } 290 291 debuglocal(4," session request ok\n"); 292 293 if (!NT_STATUS_IS_OK(cli_negprot(c))) { 294 cli_shutdown(c); 295 return 5; 296 } 297 298 debuglocal(4," session setuping for <%s>/<********> in <%s> %08x %08x %08x\n", srv->username, workgroup, c->protocol, c->sec_mode, c->capabilities); 299 300 if (!NT_STATUS_IS_OK(cli_session_setup(c, srv->username, 301 srv->password, strlen(srv->password), 302 srv->password, strlen(srv->password), 303 workgroup))) 304 { 305 debuglocal(4,"%s/******** login failed\n", srv->username); 306 loginerror = 1; // save the login error 307 308 // try an anonymous login if it failed 309 if (!NT_STATUS_IS_OK(cli_session_setup(c, "", "", 0,"", 0, workgroup))) { 310 debuglocal(4,"Anonymous login failed\n"); 311 cli_shutdown(c); 312 return 6; 313 } 314 debuglocal(4,"Anonymous login successful\n"); 315 status = cli_init_creds(c, "", lp_workgroup(), ""); 316 } else { 317 status = cli_init_creds(c, srv->username, workgroup, srv->password); 318 } 319 320 if (!NT_STATUS_IS_OK(status)) { 321 debuglocal(4,"cli_init_creds() failed\n"); 322 cli_shutdown(c); 323 // if loginerror is != 0 means normal login failed, but anonymous login worked 324 if (loginerror !=0) 325 return 6; 326 else 327 return 7; 328 } 329 330 debuglocal(4," session setup ok. Sending tconx <%s> <********>\n", share); 331 332 // YD ticket:58 we need to check resource type to avoid connecting to printers. 333 // dev type is set to IPC for IPC$, A: for everything else (printers use LPT1:) 334 if (!strcmp( share, "IPC$")) 335 dev_type = "IPC"; 336 else 337 dev_type = "A:"; 338 339 if (!NT_STATUS_IS_OK(cli_tcon_andx(c, share, dev_type, 340 srv->password, strlen(srv->password)+1))) 341 { 342 cli_shutdown(c); 343 // if loginerror is != 0 means normal login failed, but anonymous login worked 344 if (loginerror !=0) 345 return 6; 346 else 347 return 7; 348 } 349 350 debuglocal(4," tconx ok. cli caps %08x\n", c->capabilities); 364 351 365 366 367 368 369 } 370 371 /* ****************************************************372 close a connection to a server373 *******************************************************/352 // save cli_state pointer 353 *cli = c; 354 355 return 0; 356 } 357 358 /* 359 * close a connection to a server 360 */ 374 361 void _System smbwrp_disconnect( Resource* pRes, cli_state * cli) 375 362 { 376 if (pRes && cli) 377 { 378 // this call will free all buffers, close handles and free cli mem 379 cli_shutdown( cli); 380 } 381 } 382 383 384 385 /***************************************************** 386 a wrapper for open() 387 *******************************************************/ 363 // this call will free all buffers, close handles and free cli mem 364 if (pRes && cli) 365 cli_shutdown( cli); 366 } 367 368 /* 369 * a wrapper for open() 370 */ 388 371 int _System smbwrp_open(cli_state * cli, smbwrp_file * file) 389 372 { 390 uint16_t fd = 0; 391 392 if (!cli || !file || !*file->fname) 393 { 394 return maperror(EINVAL); 395 } 396 if (file->denymode < DENY_ALL || file->denymode > DENY_NONE) 397 { 398 file->denymode = DENY_NONE; 399 } 400 401 debuglocal(4,"cli_open(%s) attr %08x mode %02x denymode %02x\n", file->fname, file->openattr, file->openmode, file->denymode); 402 if (!NT_STATUS_IS_OK(cli_open(cli, file->fname, file->openmode, file->denymode, &fd))) 403 { 404 return os2cli_errno(cli); 405 } 406 file->fd = fd; 407 file->updatetime = 0; 408 file->offset = 0; 409 return 0; 410 } 411 412 /***************************************************** 413 a wrapper for read() 414 *******************************************************/ 373 uint16_t fd = 0; 374 375 if (!cli || !file || !*file->fname) 376 return maperror(EINVAL); 377 378 if (file->denymode < DENY_ALL || file->denymode > DENY_NONE) 379 file->denymode = DENY_NONE; 380 381 debuglocal(4,"cli_open(%s) attr %08x mode %02x denymode %02x\n", file->fname, file->openattr, file->openmode, file->denymode); 382 if (!NT_STATUS_IS_OK(cli_open(cli, file->fname, file->openmode, file->denymode, &fd))) 383 return os2cli_errno(cli); 384 385 file->fd = fd; 386 file->updatetime = 0; 387 file->offset = 0; 388 return 0; 389 } 390 391 /* 392 * a wrapper for read() 393 */ 415 394 int _System smbwrp_read(cli_state * cli, smbwrp_file * file, void *buf, unsigned long count, unsigned long * result) 416 395 { 417 int ret; 418 419 if (!cli || !file || !buf || !result) 420 { 421 return maperror(EINVAL); 422 } 396 int ret; 397 398 if (!cli || !file || !buf || !result) 399 return maperror(EINVAL); 423 400 424 *result = 0; 425 ret = cli_read(cli, file->fd, buf, file->offset, count); 426 if (ret == -1) 427 { 428 return os2cli_errno(cli); 429 } 430 431 file->offset += ret; 432 *result = ret; 433 return 0; 434 } 435 401 *result = 0; 402 ret = cli_read(cli, file->fd, buf, file->offset, count); 403 if (ret == -1) 404 return os2cli_errno(cli); 405 406 file->offset += ret; 407 *result = ret; 408 return 0; 409 } 410 411 /* 412 * a wrapper for write() 413 */ 414 int _System smbwrp_write(cli_state * cli, smbwrp_file * file, void *buf, unsigned long count, unsigned long * result) 415 { 416 NTSTATUS status; 417 size_t ret; 418 419 if (!cli || !file || !buf || !result) 420 return maperror(EINVAL); 436 421 437 438 /***************************************************** 439 a wrapper for write() 440 *******************************************************/ 441 int _System smbwrp_write(cli_state * cli, smbwrp_file * file, void *buf, unsigned long count, unsigned long * result) 442 { 443 NTSTATUS status; 444 size_t ret; 445 446 if (!cli || !file || !buf || !result) 447 { 448 return maperror(EINVAL); 449 } 422 *result = 0; 423 //debuglocal(1,("Write %x %d %lld %d", cli, file->fd, file->offset, count)); 424 status = cli_writeall(cli, file->fd, 0, buf, file->offset, count, &ret); 425 if (!NT_STATUS_IS_OK(status)) 426 return os2cli_errno(cli); 427 428 file->updatetime = 1; 429 file->offset += ret; 430 *result = ret; 431 return 0; 432 } 433 434 /* 435 * a wrapper for close() 436 */ 437 int _System smbwrp_close(cli_state * cli, smbwrp_file * file) 438 { 439 int rc = 0; 440 if (!cli || !file) 441 return maperror(EINVAL); 442 443 debuglocal(4,"smpwrp_close updatetime: %d\n", file->updatetime); 444 445 if (file->updatetime == 1) 446 { 447 file->mtime = time(NULL); 448 debuglocal(4,"cli_close new mtime %lu\n", file->mtime); 449 } 450 450 451 *result = 0; 452 //debuglocal(1,("Write %x %d %lld %d", cli, file->fd, file->offset, count)); 453 status = cli_writeall(cli, file->fd, 0, buf, file->offset, count, &ret); 454 if (!NT_STATUS_IS_OK(status)) { 455 return os2cli_errno(cli); 456 } 457 458 file->updatetime = 1; 459 file->offset += ret; 460 *result = ret; 461 return 0; 462 } 463 464 /***************************************************** 465 a wrapper for close() 466 *******************************************************/ 467 int _System smbwrp_close(cli_state * cli, smbwrp_file * file) 468 { 469 int rc = 0; 470 if (!cli || !file) 471 { 472 return maperror(EINVAL); 473 } 474 475 debuglocal(4,"smpwrp_close updatetime: %d\n", file->updatetime); 476 477 if (file->updatetime == 1) 478 { 479 file->mtime = time(NULL); 480 debuglocal(4,"cli_close new mtime %lu\n", file->mtime); 481 } 451 if (!NT_STATUS_IS_OK(cli_close(cli, file->fd))) 452 rc = os2cli_errno(cli); 453 454 if (!rc && (file->openattr || file->mtime || file->ctime)) 455 { 456 debuglocal(4,"Set pathinfo on close %s %08x %d %d\n", file->fname, file->openattr, file->mtime, file->ctime); 457 if (!NT_STATUS_IS_OK(cli_setpathinfo_basic(cli, file->fname, file->ctime, 0, file->mtime, 0, file->openattr))) 458 debuglocal(4,"Set pathinfo on close failed %d\n", os2cli_errno(cli)); 459 } 460 461 file->openattr = 0; 462 file->mtime = 0; 463 file->ctime = 0; 464 file->updatetime = 0; 465 file->fd = -1; 466 file->offset = 0; 467 *file->fname = 0; 468 return rc; 469 } 470 471 int _System smbwrp_setfilesize(cli_state * cli, smbwrp_file * file, long long newsize) 472 { 473 int rc = 0; 474 if (!cli || !file) 475 return maperror(EINVAL); 476 477 debuglocal(4,"cli_setnewfilesize(%s) %lld\n", file->fname, newsize); 478 if (!NT_STATUS_IS_OK(cli_ftruncate(cli, file->fd, newsize))) 479 { 480 if (newsize) 481 rc = os2cli_errno(cli); 482 483 if (!NT_STATUS_IS_OK(cli_close(cli, file->fd))) 484 return os2cli_errno(cli); 485 486 uint16_t fd = 0; 487 file->fd = -1; 488 file->offset = 0; 489 file->openmode &= ~(O_CREAT | O_EXCL); 490 file->openmode |= O_TRUNC; 491 debuglocal(4,"cli_setnewfileszie : cli_open(%s) attr %08x mode %02x denymode %02x\n", file->fname, file->openattr, file->openmode, file->denymode); 492 if (!NT_STATUS_IS_OK(cli_open(cli, file->fname, file->openmode, file->denymode, &fd))) 493 return os2cli_errno(cli); 494 495 file->fd = fd; 496 } 497 return 0; 498 } 499 500 /* 501 * a wrapper for rename() 502 */ 503 int _System smbwrp_rename(cli_state * cli, char *oldname, char *newname) 504 { 505 if (!cli || !oldname || !newname) 506 return maperror(EINVAL); 507 508 debuglocal(1,"Rename <%s> -> <%s>\n", oldname, newname); 509 if (!NT_STATUS_IS_OK(cli_rename(cli, oldname, newname))) 510 return os2cli_errno(cli); 511 512 return 0; 513 } 514 515 516 /* 517 * a wrapper for chmod() 518 */ 519 int _System smbwrp_setattr(cli_state * cli, smbwrp_fileinfo *finfo) 520 { 521 if (!cli || !finfo || !*finfo->fname) 522 return maperror(EINVAL); 523 524 debuglocal(4,"Setting on <%s> attr %04x, time %lu (timezone /%lu\n", finfo->fname, finfo->attr, finfo->mtime, finfo->mtime + get_time_zone(finfo->mtime)); 525 // we already have gmt time, so no need to add timezone 526 // if (!cli_setatr(cli, finfo->fname, finfo->attr, finfo->mtime + (finfo->mtime == 0 ? 0 : get_time_zone(finfo->mtime))) 527 if (!NT_STATUS_IS_OK(cli_setatr(cli, finfo->fname, finfo->attr, finfo->mtime)) 528 && !NT_STATUS_IS_OK(cli_setatr(cli, finfo->fname, finfo->attr, 0))) 529 return os2cli_errno(cli); 482 530 483 if (!NT_STATUS_IS_OK(cli_close(cli, file->fd))) 484 { 485 rc = os2cli_errno(cli); 486 } 487 488 if (!rc && (file->openattr || file->mtime || file->ctime)) 489 { 490 debuglocal(4,"Set pathinfo on close %s %08x %d %d\n", file->fname, file->openattr, file->mtime, file->ctime); 491 if (!NT_STATUS_IS_OK(cli_setpathinfo_basic(cli, file->fname, file->ctime, 0, file->mtime, 0, file->openattr))) 492 { 493 debuglocal(4,"Set pathinfo on close failed %d\n", os2cli_errno(cli)); 494 //rc = os2cli_errno(cli); 495 } 496 } 497 498 file->openattr = 0; 499 file->mtime = 0; 500 file->ctime = 0; 501 file->updatetime = 0; 502 file->fd = -1; 503 file->offset = 0; 504 *file->fname = 0; 505 return rc; 506 } 507 508 int _System smbwrp_setfilesize(cli_state * cli, smbwrp_file * file, long long newsize) 509 { 510 int rc = 0; 511 if (!cli || !file) 512 { 513 return maperror(EINVAL); 514 } 515 516 debuglocal(4,"cli_setnewfilesize(%s) %lld\n", file->fname, newsize); 517 if (!NT_STATUS_IS_OK(cli_ftruncate(cli, file->fd, newsize))) 518 { 519 if (newsize) 520 { 521 rc = os2cli_errno(cli); 522 } 523 524 if (!NT_STATUS_IS_OK(cli_close(cli, file->fd))) 525 { 526 return os2cli_errno(cli); 527 } 528 uint16_t fd = 0; 529 file->fd = -1; 530 file->offset = 0; 531 file->openmode &= ~(O_CREAT | O_EXCL); 532 file->openmode |= O_TRUNC; 533 debuglocal(4,"cli_setnewfileszie : cli_open(%s) attr %08x mode %02x denymode %02x\n", file->fname, file->openattr, file->openmode, file->denymode); 534 if (!NT_STATUS_IS_OK(cli_open(cli, file->fname, file->openmode, file->denymode, &fd))) 535 { 536 return os2cli_errno(cli); 537 } 538 file->fd = fd; 539 } 540 return 0; 541 } 542 543 /***************************************************** 544 a wrapper for rename() 545 *******************************************************/ 546 int _System smbwrp_rename(cli_state * cli, char *oldname, char *newname) 547 { 548 if (!cli || !oldname || !newname) 549 { 550 return maperror(EINVAL); 551 } 552 553 debuglocal(1,"Rename <%s> -> <%s>\n", oldname, newname); 554 if (!NT_STATUS_IS_OK(cli_rename(cli, oldname, newname))) 555 { 556 return os2cli_errno(cli); 557 } 558 return 0; 559 } 560 561 562 /***************************************************** 563 a wrapper for chmod() 564 *******************************************************/ 565 int _System smbwrp_setattr(cli_state * cli, smbwrp_fileinfo *finfo) 566 { 567 if (!cli || !finfo || !*finfo->fname) 568 { 569 return maperror(EINVAL); 570 } 571 572 debuglocal(4,"Setting on <%s> attr %04x, time %lu (timezone /%lu\n", finfo->fname, finfo->attr, finfo->mtime, finfo->mtime + get_time_zone(finfo->mtime)); 573 // we already have gmt time, so no need to add timezone 574 // if (!cli_setatr(cli, finfo->fname, finfo->attr, finfo->mtime + (finfo->mtime == 0 ? 0 : get_time_zone(finfo->mtime))) 575 if (!NT_STATUS_IS_OK(cli_setatr(cli, finfo->fname, finfo->attr, finfo->mtime)) 576 && !NT_STATUS_IS_OK(cli_setatr(cli, finfo->fname, finfo->attr, 0))) 577 { 578 return os2cli_errno(cli); 579 } 580 return 0; 581 } 582 583 /***************************************************** 584 a wrapper for unlink() 585 *******************************************************/ 531 return 0; 532 } 533 534 /* 535 * a wrapper for unlink() 536 */ 586 537 int _System smbwrp_unlink(cli_state * cli, const char *fname) 587 538 { 588 if (!cli || !fname) 589 { 590 return maperror(EINVAL); 591 } 539 if (!cli || !fname) 540 return maperror(EINVAL); 541 592 542 #if 0 593 if (strncmp(cli->dev, "LPT", 3) == 0) 594 { 595 int job = smbw_stat_printjob(cli, fname, NULL, NULL); 596 if (job == -1) 597 { 598 goto failed; 599 } 600 if (cli_printjob_del(cli, job) != 0) 601 { 602 goto failed; 603 } 604 } else 543 if (strncmp(cli->dev, "LPT", 3) == 0) 544 { 545 int job = smbw_stat_printjob(cli, fname, NULL, NULL); 546 if (job == -1) 547 goto failed; 548 549 if (cli_printjob_del(cli, job) != 0) 550 goto failed; 551 552 } else 605 553 #endif 606 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) 607 { 608 return os2cli_errno(cli); 609 } 610 return 0; 611 } 612 613 /***************************************************** 614 a wrapper for lseek() 615 *******************************************************/ 554 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) 555 return os2cli_errno(cli); 556 557 return 0; 558 } 559 560 /* 561 * a wrapper for lseek() 562 */ 616 563 int _System smbwrp_lseek(cli_state * cli, smbwrp_file * file, int whence, long long offset) 617 564 { 618 off_t size; 619 if (!cli || !file) 620 { 621 return maperror(EINVAL); 622 } 623 624 debuglocal(4,"lseek %d %lld %lld\n", whence, offset, file->offset); 625 626 switch (whence) { 627 case SEEK_SET: 628 if (offset < 0) 629 { 630 return maperror(EINVAL); 631 } 632 file->offset = offset; 633 break; 634 case SEEK_CUR: 635 file->offset += offset; 636 break; 637 case SEEK_END: 638 if (offset > 0) 639 { 640 return maperror(EINVAL); 641 } 642 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(cli, file->fd, 643 NULL, &size, NULL, NULL, NULL, 644 NULL, NULL)) && 645 !NT_STATUS_IS_OK(cli_getattrE(cli, file->fd, 646 NULL, &size, NULL, NULL, NULL))) 647 { 648 return os2cli_errno(cli); 649 } 650 file->offset = size + offset; 651 break; 652 default: return maperror(EINVAL); 653 } 654 655 return 0; 656 } 657 658 /***************************************************** 659 try to do a QPATHINFO and if that fails then do a getatr 660 this is needed because win95 sometimes refuses the qpathinfo 661 *******************************************************/ 565 off_t size; 566 if (!cli || !file) 567 return maperror(EINVAL); 568 569 debuglocal(4,"lseek %d %lld %lld\n", whence, offset, file->offset); 570 571 switch (whence) { 572 case SEEK_SET: 573 if (offset < 0) 574 return maperror(EINVAL); 575 file->offset = offset; 576 break; 577 case SEEK_CUR: 578 file->offset += offset; 579 break; 580 case SEEK_END: 581 if (offset > 0) 582 return maperror(EINVAL); 583 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(cli, file->fd, 584 NULL, &size, NULL, NULL, NULL,NULL, NULL)) && 585 !NT_STATUS_IS_OK(cli_getattrE(cli, file->fd, 586 NULL, &size, NULL, NULL, NULL))) 587 return os2cli_errno(cli); 588 file->offset = size + offset; 589 break; 590 default: 591 return maperror(EINVAL); 592 } 593 594 return 0; 595 } 596 597 /* 598 * try to do a QPATHINFO and if that fails then do a getatr 599 * this is needed because win95 sometimes refuses the qpathinfo 600 */ 662 601 int _System smbwrp_getattr(smbwrp_server *srv, cli_state * cli, smbwrp_fileinfo *finfo) 663 602 { 664 SMB_INO_T ino = 0; 665 struct timespec ctime; 666 struct timespec mtime; 667 struct timespec atime; 668 669 if (!cli || !finfo || !*finfo->fname) 670 { 671 return maperror(EINVAL); 672 } 673 debuglocal(4,"getattr %d %d <%s>\n", cli->capabilities & CAP_NOPATHINFO2, cli->capabilities & CAP_NT_SMBS, finfo->fname); 674 if (!(cli->capabilities & CAP_NOPATHINFO2) && 675 NT_STATUS_IS_OK(cli_qpathinfo2(cli, finfo->fname, &ctime, &atime, &mtime, NULL, 676 (off_t *)&finfo->size, (unsigned short *)&finfo->attr, &ino))) 677 { 678 finfo->attr &= 0x7F; 679 finfo->ctime = convert_timespec_to_time_t(ctime); 680 finfo->atime = convert_timespec_to_time_t(atime); 681 finfo->mtime = convert_timespec_to_time_t(mtime); 682 return 0; 683 } 684 685 if (cli->fd == -1) 686 { 687 /* fd == -1 means the connection is broken */ 688 return maperror(ENOTCONN); 689 } 690 691 /* If the path is not on a share (it is a workgroup or a server), 692 * then cli_qpathinfo2 obviously fails. Return some fake information 693 * about the directory. 694 */ 695 if ( *srv->server_name == 0 696 || (strcmp(cli->dev,"IPC") == 0) 697 || *srv->share_name == 0 698 || (stricmp(srv->share_name,"IPC$") == 0) 699 || (strncmp(cli->dev,"LPT",3) == 0) 700 ) 701 { 702 debuglocal(4,"getattr not a share.\n"); 703 *(time_t *)&finfo->ctime = time (NULL); 704 *(time_t *)&finfo->atime = time (NULL); 705 *(time_t *)&finfo->mtime = time (NULL); 706 finfo->size = 0; 707 finfo->easize = 0; 708 finfo->attr = aDIR; 709 return 0; 710 } 603 SMB_INO_T ino = 0; 604 struct timespec ctime; 605 struct timespec mtime; 606 struct timespec atime; 607 608 if (!cli || !finfo || !*finfo->fname) 609 return maperror(EINVAL); 610 611 debuglocal(4,"getattr %d %d <%s>\n", cli->capabilities & CAP_NOPATHINFO2, cli->capabilities & CAP_NT_SMBS, finfo->fname); 612 if (!(cli->capabilities & CAP_NOPATHINFO2) && 613 NT_STATUS_IS_OK(cli_qpathinfo2(cli, finfo->fname, &ctime, &atime, 614 &mtime, NULL, (off_t *)&finfo->size, (unsigned short *)&finfo->attr, 615 &ino))) 616 { 617 finfo->attr &= 0x7F; 618 finfo->ctime = convert_timespec_to_time_t(ctime); 619 finfo->atime = convert_timespec_to_time_t(atime); 620 finfo->mtime = convert_timespec_to_time_t(mtime); 621 return 0; 622 } 623 624 // fd == -1 means the connection is broken */ 625 if (cli->fd == -1) 626 return maperror(ENOTCONN); 627 628 /* If the path is not on a share (it is a workgroup or a server), 629 * then cli_qpathinfo2 obviously fails. Return some fake information 630 * about the directory. 631 */ 632 if (*srv->server_name == 0 633 || (strcmp(cli->dev,"IPC") == 0) 634 || *srv->share_name == 0 635 || (stricmp(srv->share_name,"IPC$") == 0) 636 || (strncmp(cli->dev,"LPT",3) == 0)) 637 { 638 debuglocal(4,"getattr not a share.\n"); 639 *(time_t *)&finfo->ctime = time (NULL); 640 *(time_t *)&finfo->atime = time (NULL); 641 *(time_t *)&finfo->mtime = time (NULL); 642 finfo->size = 0; 643 finfo->easize = 0; 644 finfo->attr = aDIR; 645 return 0; 646 } 711 647 712 /* if this is NT then don't bother with the getatr */ 713 if (cli->capabilities & CAP_NT_SMBS && !(cli->capabilities & CAP_NOPATHINFO2)) 714 { 715 int ret = cli_errno(cli); 716 // cli_qpathinfo* reports EINVAL when path of given file not exists 717 // thus there is no real situation when EINVAL should be returned to 718 // client at this point, we just replace it to ENOTDIR 719 if (ret == EINVAL) 720 { 721 ret = ENOTDIR; 722 } 723 return maperror(ret); 724 } 725 726 if (NT_STATUS_IS_OK(cli_getatr(cli, finfo->fname, (unsigned short *)&finfo->attr, &finfo->size, (time_t *)&finfo->mtime))) 727 { 728 //debuglocal(2,("gotattr1 %08x <%s>\n", finfo->attr, finfo->fname)); 729 finfo->mtime -= get_time_zone(finfo->mtime); 730 finfo->atime = finfo->atime; //was mtime 731 finfo->ctime = finfo->ctime; //was mtime 732 cli->capabilities &= CAP_NOPATHINFO2; 733 return 0; 734 } 735 return os2cli_errno(cli); 736 } 737 738 /***************************************************** 739 try to do a QPATHINFO and if that fails then do a getatr 740 this is needed because win95 sometimes refuses the qpathinfo 741 *******************************************************/ 648 // if this is NT then don't bother with the getatr */ 649 if (cli->capabilities & CAP_NT_SMBS && !(cli->capabilities & CAP_NOPATHINFO2)) 650 { 651 int ret = cli_errno(cli); 652 /* 653 * cli_qpathinfo* reports EINVAL when path of given file not exists 654 * thus there is no real situation when EINVAL should be returned to 655 * client at this point, we just replace it to ENOTDIR 656 */ 657 if (ret == EINVAL) 658 ret = ENOTDIR; 659 660 return maperror(ret); 661 } 662 663 if (NT_STATUS_IS_OK(cli_getatr(cli, finfo->fname, (unsigned short *)&finfo->attr, &finfo->size, (time_t *)&finfo->mtime))) 664 { 665 //debuglocal(2,("gotattr1 %08x <%s>\n", finfo->attr, finfo->fname)); 666 finfo->mtime -= get_time_zone(finfo->mtime); 667 finfo->atime = finfo->atime; //was mtime 668 finfo->ctime = finfo->ctime; //was mtime 669 cli->capabilities &= CAP_NOPATHINFO2; 670 return 0; 671 } 672 673 return os2cli_errno(cli); 674 } 675 676 /* 677 * try to do a QPATHINFO and if that fails then do a getatr 678 * this is needed because win95 sometimes refuses the qpathinfo 679 */ 742 680 int _System smbwrp_fgetattr(cli_state * cli, smbwrp_file *file, smbwrp_fileinfo *finfo) 743 681 { 744 struct timespec ctime; 745 struct timespec mtime; 746 struct timespec atime; 747 SMB_INO_T ino = 0; 748 749 if (!cli || !file || !finfo) 750 { 751 return maperror(EINVAL); 752 } 753 754 strncpy(finfo->fname, file->fname, sizeof(finfo->fname) - 1); 755 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(cli, file->fd, 756 (unsigned short *)&finfo->attr, (off_t *)&finfo->size, &ctime, &atime, &mtime, NULL, 757 &ino))) 758 { 759 if (!NT_STATUS_IS_OK(cli_getattrE(cli, file->fd, 760 (unsigned short *)&finfo->attr, (&finfo->size), (time_t *)&finfo->ctime, (time_t *)&finfo->atime, (time_t *)&finfo->mtime))) 761 { 762 return os2cli_errno(cli); 763 } 764 else 765 { 766 finfo->ctime -= get_time_zone(finfo->ctime); 767 finfo->atime -= get_time_zone(finfo->atime); 768 finfo->mtime -= get_time_zone(finfo->mtime); 769 } 770 } 771 else 772 { 773 finfo->ctime = convert_timespec_to_time_t(ctime); 774 finfo->atime = convert_timespec_to_time_t(atime); 775 finfo->mtime = convert_timespec_to_time_t(mtime); 776 } 777 778 return 0; 682 struct timespec ctime; 683 struct timespec mtime; 684 struct timespec atime; 685 SMB_INO_T ino = 0; 686 687 if (!cli || !file || !finfo) 688 return maperror(EINVAL); 689 690 691 strncpy(finfo->fname, file->fname, sizeof(finfo->fname) - 1); 692 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(cli, file->fd, 693 (unsigned short *)&finfo->attr, (off_t *)&finfo->size, &ctime, 694 &atime, &mtime, NULL, &ino))) 695 { 696 if (!NT_STATUS_IS_OK(cli_getattrE(cli, file->fd, 697 (unsigned short *)&finfo->attr, (&finfo->size), 698 (time_t *)&finfo->ctime, (time_t *)&finfo->atime, 699 (time_t *)&finfo->mtime))) 700 return os2cli_errno(cli); 701 else 702 { 703 finfo->ctime -= get_time_zone(finfo->ctime); 704 finfo->atime -= get_time_zone(finfo->atime); 705 finfo->mtime -= get_time_zone(finfo->mtime); 706 } 707 } 708 else 709 { 710 finfo->ctime = convert_timespec_to_time_t(ctime); 711 finfo->atime = convert_timespec_to_time_t(atime); 712 finfo->mtime = convert_timespec_to_time_t(mtime); 713 } 714 715 return 0; 779 716 } 780 717 781 718 // =============================DIRECTORY ROUTINES============================ 782 719 783 /* ****************************************************784 add a entry to a directory listing785 *******************************************************/720 /* 721 * add a entry to a directory listing 722 */ 786 723 static void smbwrp_dir_add(const char* mnt, smbwrp_fileinfo *finfo, const char *mask, void *state) 787 724 { 788 if (state && finfo) 789 { 790 filelist_state * st = (filelist_state *)state; 791 char fullname[ _MAX_PATH] = {0}; 792 debuglocal(8,"adding <%s> %d %d %d\n", finfo->fname, sizeof(st->finfo), st->datalen, sizeof(st->finfo.fname)); 793 memcpy(&st->finfo, finfo, sizeof(st->finfo)); 794 strncpy(fullname, st->dir, strlen(st->dir)); 795 strncat(fullname, finfo->fname, sizeof(fullname) - strlen(fullname) -1); 796 strncpy(st->finfo.fname, fullname, sizeof(st->finfo.fname)); 797 getfindinfoL( st->pConn, st->plist, &st->finfo, st->ulAttribute, st->dir_mask); 798 } 725 if (state && finfo) 726 { 727 filelist_state * st = (filelist_state *)state; 728 char fullname[ _MAX_PATH] = {0}; 729 debuglocal(8,"adding <%s> %d %d %d\n", finfo->fname, sizeof(st->finfo), st->datalen, sizeof(st->finfo.fname)); 730 memcpy(&st->finfo, finfo, sizeof(st->finfo)); 731 strncpy(fullname, st->dir, strlen(st->dir)); 732 strncat(fullname, finfo->fname, sizeof(fullname) - strlen(fullname) -1); 733 strncpy(st->finfo.fname, fullname, sizeof(st->finfo.fname)); 734 getfindinfoL( st->pConn, st->plist, &st->finfo, st->ulAttribute, st->dir_mask); 735 } 736 return; 799 737 } 800 738 801 739 static void smbwrp_special_add(const char * name, void * state) 802 740 { 803 smbwrp_fileinfo finfo = {0}; 804 805 if (!name) 806 { 807 return; 808 } 809 810 ZERO_STRUCT(finfo); 811 812 strncpy(finfo.fname, name, sizeof(finfo.fname) - 1); 813 finfo.attr = aRONLY | aDIR; 814 815 smbwrp_dir_add("", &finfo, NULL, state); 741 smbwrp_fileinfo finfo = {0}; 742 743 if (!name) 744 return; 745 746 ZERO_STRUCT(finfo); 747 748 strncpy(finfo.fname, name, sizeof(finfo.fname) - 1); 749 finfo.attr = aRONLY | aDIR; 750 751 smbwrp_dir_add("", &finfo, NULL, state); 752 return; 816 753 } 817 754 818 755 static void smbwrp_printjob_add(struct print_job_info *job, void * state) 819 756 { 820 smbwrp_fileinfo finfo = {0}; 821 822 ZERO_STRUCT(finfo); 823 824 //printf("Printjob <%s>\n", job->name); 825 826 strncpy(finfo.fname, job->name, sizeof(finfo.fname) - 1); 827 finfo.mtime = job->t - get_time_zone(job->t); 828 finfo.atime = finfo.atime; //was mtime 829 finfo.ctime = finfo.ctime; //was mtime 830 finfo.attr = aRONLY; 831 finfo.size = job->size; 832 833 smbwrp_dir_add("", &finfo, NULL, state); 757 smbwrp_fileinfo finfo = {0}; 758 759 ZERO_STRUCT(finfo); 760 761 //printf("Printjob <%s>\n", job->name); 762 763 strncpy(finfo.fname, job->name, sizeof(finfo.fname) - 1); 764 finfo.mtime = job->t - get_time_zone(job->t); 765 finfo.atime = finfo.atime; //was mtime 766 finfo.ctime = finfo.ctime; //was mtime 767 finfo.attr = aRONLY; 768 finfo.size = job->size; 769 770 smbwrp_dir_add("", &finfo, NULL, state); 771 return; 834 772 } 835 773 … … 837 775 const char *comment, void *state) 838 776 { 839 smbwrp_fileinfo finfo = {0}; 840 841 // strip administrative names and printers from list 842 if (type == STYPE_PRINTQ || strcmp(share,"IPC$") == 0) return; 843 844 ZERO_STRUCT(finfo); 845 846 strncpy(finfo.fname, share, sizeof(finfo.fname) - 1); 847 finfo.attr = aRONLY | aDIR; 848 849 smbwrp_dir_add("", &finfo, NULL, state); 850 } 851 852 /**************************************************************************** 853 Do a directory listing, calling fn on each file found. 854 Modified from cli_list 855 ****************************************************************************/ 777 smbwrp_fileinfo finfo = {0}; 778 779 // strip administrative names and printers from list 780 if (type == STYPE_PRINTQ || strcmp(share,"IPC$") == 0) 781 return; 782 783 ZERO_STRUCT(finfo); 784 785 strncpy(finfo.fname, share, sizeof(finfo.fname) - 1); 786 finfo.attr = aRONLY | aDIR; 787 788 smbwrp_dir_add("", &finfo, NULL, state); 789 return; 790 } 791 792 /* 793 * Do a directory listing, calling fn on each file found. 794 * Modified from cli_list 795 */ 856 796 static int list_files(struct cli_state *cli, const char *mask, uint16 attribute, 857 797 void (*fn)(const char *, smbwrp_fileinfo *, const char *, 858 798 void *), void *state) 859 799 { 860 TALLOC_CTX *frame = talloc_stackframe(); 861 struct event_context *ev; 862 struct tevent_req *req; 863 NTSTATUS status = NT_STATUS_NO_MEMORY; 864 struct file_info *finfo; 865 size_t i, num_finfo; 866 uint16_t info_level; 867 void *dircachectx = NULL; 868 smbwrp_fileinfo wrpfinfo; 869 870 /* Try to get the listing from cache. */ 871 if (dircache_list_files(fn, state, &num_finfo)) 872 { 873 /* Got from cache. */ 874 return(num_finfo); 875 } 876 877 if (cli_has_async_calls(cli)) { 878 /* 879 * Can't use sync call while an async call is in flight 880 */ 881 status = NT_STATUS_INVALID_PARAMETER; 882 goto fail; 883 } 884 ev = event_context_init(frame); 885 if (ev == NULL) { 886 goto fail; 887 } 888 889 info_level = (cli->capabilities & CAP_NT_SMBS) 890 ? SMB_FIND_FILE_BOTH_DIRECTORY_INFO : SMB_FIND_EA_SIZE; 891 892 debuglocal(4,"list_files level %d. mask <%s>\n", info_level, mask); 893 894 req = cli_list_send(frame, ev, cli, mask, attribute, info_level); 895 if (req == NULL) { 896 goto fail; 897 } 898 if (!tevent_req_poll(req, ev)) { 899 status = map_nt_error_from_unix(errno); 900 goto fail; 901 } 902 903 status = cli_list_recv(req, frame, &finfo, &num_finfo); 904 if (!NT_STATUS_IS_OK(status)) { 905 goto fail; 906 } 907 908 dircachectx = dircache_write_begin(state, num_finfo); 909 910 debuglocal(4,"list_files: got %d files\n", num_finfo); 911 912 913 for (i=0; i<num_finfo; i++) { 914 //as samba and this client have different finfo, we need to convert 915 memset(&wrpfinfo, 0, sizeof(wrpfinfo)); 916 wrpfinfo.size = finfo[i].size; 917 wrpfinfo.attr = finfo[i].mode; 918 wrpfinfo.ctime = convert_timespec_to_time_t(finfo[i].ctime_ts); 919 wrpfinfo.mtime = convert_timespec_to_time_t(finfo[i].mtime_ts); 920 wrpfinfo.atime = convert_timespec_to_time_t(finfo[i].atime_ts); 921 wrpfinfo.easize = finfo[i].easize; 922 strncpy(wrpfinfo.fname, finfo[i].name, sizeof(wrpfinfo.fname) -1); 923 924 fn(cli->dfs_mountpoint, &wrpfinfo, mask, state); 925 // Also add the entry to the cache. 926 dircache_write_entry(dircachectx, &wrpfinfo); 927 } 928 929 dircache_write_end(dircachectx); 800 TALLOC_CTX *frame = talloc_stackframe(); 801 struct event_context *ev; 802 struct tevent_req *req; 803 NTSTATUS status = NT_STATUS_NO_MEMORY; 804 struct file_info *finfo; 805 size_t i, num_finfo; 806 uint16_t info_level; 807 void *dircachectx = NULL; 808 smbwrp_fileinfo wrpfinfo; 809 810 // Try to get the listing from cache. 811 if (dircache_list_files(fn, state, &num_finfo)) 812 return(num_finfo); // Got from cache 813 814 if (cli_has_async_calls(cli)) { 815 /* 816 * Can't use sync call while an async call is in flight 817 */ 818 status = NT_STATUS_INVALID_PARAMETER; 819 goto fail; 820 } 821 ev = event_context_init(frame); 822 if (ev == NULL) 823 goto fail; 824 825 info_level = (cli->capabilities & CAP_NT_SMBS) 826 ? SMB_FIND_FILE_BOTH_DIRECTORY_INFO : SMB_FIND_EA_SIZE; 827 828 debuglocal(4,"list_files level %d. mask <%s>\n", info_level, mask); 829 830 req = cli_list_send(frame, ev, cli, mask, attribute, info_level); 831 if (req == NULL) 832 goto fail; 833 834 if (!tevent_req_poll(req, ev)) { 835 status = map_nt_error_from_unix(errno); 836 goto fail; 837 } 838 839 status = cli_list_recv(req, frame, &finfo, &num_finfo); 840 if (!NT_STATUS_IS_OK(status)) 841 goto fail; 842 843 dircachectx = dircache_write_begin(state, num_finfo); 844 845 debuglocal(4,"list_files: got %d files\n", num_finfo); 846 847 for (i=0; i<num_finfo; i++) { 848 //as samba and this client have different finfo, we need to convert 849 memset(&wrpfinfo, 0, sizeof(wrpfinfo)); 850 wrpfinfo.size = finfo[i].size; 851 wrpfinfo.attr = finfo[i].mode; 852 wrpfinfo.ctime = convert_timespec_to_time_t(finfo[i].ctime_ts); 853 wrpfinfo.mtime = convert_timespec_to_time_t(finfo[i].mtime_ts); 854 wrpfinfo.atime = convert_timespec_to_time_t(finfo[i].atime_ts); 855 wrpfinfo.easize = finfo[i].easize; 856 strncpy(wrpfinfo.fname, finfo[i].name, sizeof(wrpfinfo.fname) -1); 857 fn(cli->dfs_mountpoint, &wrpfinfo, mask, state); 858 // Also add the entry to the cache. 859 dircache_write_entry(dircachectx, &wrpfinfo); 860 } 861 862 dircache_write_end(dircachectx); 930 863 fail: 931 932 933 } 934 935 /* ****************************************************936 open a directory on the server937 *******************************************************/864 TALLOC_FREE(frame); 865 return num_finfo; 866 } 867 868 /* 869 * open a directory on the server 870 */ 938 871 int _System smbwrp_filelist(smbwrp_server *srv, cli_state * cli, filelist_state * state) 939 872 { 940 if (!srv || !cli || !state || !*state->mask) 941 { 942 return maperror(EINVAL); 943 } 944 debuglocal(1,"Filelist <%s> on master <%s> wgrp <%s> server <%s> share <%s> clidev <%s>\n", state->mask, srv->master, srv->workgroup, srv->server_name, srv->share_name, cli->dev); 945 if (*srv->workgroup == 0 && *srv->server_name == 0) 946 { 947 smbwrp_special_add(".", state); 948 smbwrp_special_add("..", state); 949 cli_NetServerEnum(cli, srv->master, SV_TYPE_DOMAIN_ENUM, 950 smbwrp_share_add, state); 951 } else 952 if (*srv->server_name == 0) 953 { 954 smbwrp_special_add(".", state); 955 smbwrp_special_add("..", state); 956 957 cli_NetServerEnum(cli, srv->workgroup, SV_TYPE_ALL, 958 smbwrp_share_add, state); 959 } else 960 if ((strcmp(cli->dev,"IPC") == 0) || *srv->share_name == 0 || (stricmp(srv->share_name,"IPC$") == 0)) 961 { 962 smbwrp_special_add(".", state); 963 smbwrp_special_add("..", state); 964 965 if (net_share_enum_rpc(cli, smbwrp_share_add, state) < 0 && 966 cli_RNetShareEnum(cli,smbwrp_share_add, state) < 0) 967 { 968 return os2cli_errno(cli); 969 } 970 } else 971 if (strncmp(cli->dev,"LPT",3) == 0) 972 { 973 smbwrp_special_add(".", state); 974 smbwrp_special_add("..", state); 975 if (cli_print_queue_state(cli, smbwrp_printjob_add, state) < 0) 976 { 977 return os2cli_errno(cli); 978 } 979 } 980 else 981 { 982 if (list_files(cli, state->mask, aHIDDEN|aSYSTEM|aDIR, 983 smbwrp_dir_add, state) < 0) 984 { 985 return os2cli_errno(cli); 986 } 987 } 988 989 return 0; 990 } 991 992 /***************************************************** 993 a wrapper for chdir() 994 *******************************************************/ 873 if (!srv || !cli || !state || !*state->mask) 874 return maperror(EINVAL); 875 876 debuglocal(1,"Filelist <%s> on master <%s> wgrp <%s> server <%s> share <%s> clidev <%s>\n", state->mask, srv->master, srv->workgroup, srv->server_name, srv->share_name, cli->dev); 877 if (*srv->workgroup == 0 && *srv->server_name == 0) 878 { 879 smbwrp_special_add(".", state); 880 smbwrp_special_add("..", state); 881 cli_NetServerEnum(cli, srv->master, SV_TYPE_DOMAIN_ENUM, 882 smbwrp_share_add, state); 883 } else if (*srv->server_name == 0) 884 { 885 smbwrp_special_add(".", state); 886 smbwrp_special_add("..", state); 887 cli_NetServerEnum(cli, srv->workgroup, SV_TYPE_ALL, 888 smbwrp_share_add, state); 889 } else if ((strcmp(cli->dev,"IPC") == 0) || *srv->share_name == 0 || 890 (stricmp(srv->share_name,"IPC$") == 0)) 891 { 892 smbwrp_special_add(".", state); 893 smbwrp_special_add("..", state); 894 if (net_share_enum_rpc(cli, smbwrp_share_add, state) < 0 && 895 cli_RNetShareEnum(cli,smbwrp_share_add, state) < 0) 896 return os2cli_errno(cli); 897 } else if (strncmp(cli->dev,"LPT",3) == 0) 898 { 899 smbwrp_special_add(".", state); 900 smbwrp_special_add("..", state); 901 if (cli_print_queue_state(cli, smbwrp_printjob_add, state) < 0) 902 return os2cli_errno(cli); 903 } 904 else 905 { 906 if (list_files(cli, state->mask, aHIDDEN|aSYSTEM|aDIR, 907 smbwrp_dir_add, state) < 0) 908 return os2cli_errno(cli); 909 } 910 911 return 0; 912 } 913 914 /* 915 * a wrapper for chdir() 916 */ 995 917 int _System smbwrp_chdir(smbwrp_server *srv, cli_state * cli, char *fname) 996 918 { 997 unsigned short mode = aDIR; 998 smbwrp_fileinfo finfo = {0}; 999 if (!cli || !fname) 1000 { 1001 return maperror(EINVAL); 1002 } 1003 1004 strncpy(finfo.fname, fname, sizeof(finfo.fname) - 1); 1005 if (smbwrp_getattr(srv, cli, &finfo)) 1006 { 1007 return os2cli_errno(cli); 1008 } 1009 1010 if (!(finfo.attr & aDIR)) { 1011 return maperror(ENOTDIR); 1012 } 1013 1014 return 0; 1015 } 1016 1017 1018 /***************************************************** 1019 a wrapper for mkdir() 1020 *******************************************************/ 919 unsigned short mode = aDIR; 920 smbwrp_fileinfo finfo = {0}; 921 if (!cli || !fname) 922 return maperror(EINVAL); 923 924 strncpy(finfo.fname, fname, sizeof(finfo.fname) - 1); 925 if (smbwrp_getattr(srv, cli, &finfo)) 926 return os2cli_errno(cli); 927 928 929 if (!(finfo.attr & aDIR)) 930 return maperror(ENOTDIR); 931 932 933 return 0; 934 } 935 936 937 /* 938 * a wrapper for mkdir() 939 */ 1021 940 int _System smbwrp_mkdir(cli_state * cli, char *fname) 1022 941 { 1023 if (!cli || !fname) 1024 { 1025 return maperror(EINVAL); 1026 } 1027 1028 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) 1029 { 1030 return os2cli_errno(cli); 1031 } 1032 return 0; 1033 } 1034 1035 /***************************************************** 1036 a wrapper for rmdir() 1037 *******************************************************/ 942 if (!cli || !fname) 943 return maperror(EINVAL); 944 945 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) 946 return os2cli_errno(cli); 947 948 return 0; 949 } 950 951 /* 952 * a wrapper for rmdir() 953 */ 1038 954 int _System smbwrp_rmdir(cli_state * cli, char *fname) 1039 955 { 1040 if (!cli || !fname) 1041 { 1042 return maperror(EINVAL); 1043 } 1044 1045 if (!NT_STATUS_IS_OK(cli_rmdir(cli, fname))) 1046 { 1047 return os2cli_errno(cli); 1048 } 1049 return 0; 1050 } 1051 1052 /***************************************************** 1053 set EA for a path 1054 *******************************************************/ 956 if (!cli || !fname) 957 return maperror(EINVAL); 958 959 if (!NT_STATUS_IS_OK(cli_rmdir(cli, fname))) 960 return os2cli_errno(cli); 961 962 return 0; 963 } 964 965 /* 966 * set EA for a path 967 */ 1055 968 int _System smbwrp_setea(cli_state * cli, char *fname, char * name, unsigned char * value, int size) 1056 969 { 1057 if (!cli || !fname || !name) 1058 { 1059 return maperror(EINVAL); 1060 } 1061 if (!NT_STATUS_IS_OK(cli_set_ea_path(cli, fname, name, value, size))) 1062 { 1063 return os2cli_errno(cli); 1064 } 1065 return 0; 1066 } 1067 1068 /***************************************************** 1069 set EA for a file 1070 *******************************************************/ 970 if (!cli || !fname || !name) 971 return maperror(EINVAL); 972 973 if (!NT_STATUS_IS_OK(cli_set_ea_path(cli, fname, name, value, size))) 974 return os2cli_errno(cli); 975 976 return 0; 977 } 978 979 /* 980 * set EA for a file 981 */ 1071 982 int _System smbwrp_fsetea(cli_state * cli, smbwrp_file *file, char * name, unsigned char * value, int size) 1072 983 { 1073 if (!cli || !file || !name) 1074 { 1075 return maperror(EINVAL); 1076 } 1077 if (!NT_STATUS_IS_OK(cli_set_ea_fnum(cli, file->fd, name, value, size))) 1078 { 1079 return os2cli_errno(cli); 1080 } 1081 return 0; 984 if (!cli || !file || !name) 985 return maperror(EINVAL); 986 987 if (!NT_STATUS_IS_OK(cli_set_ea_fnum(cli, file->fd, name, value, size))) 988 return os2cli_errno(cli); 989 990 return 0; 1082 991 } 1083 992 1084 993 1085 994 #pragma pack(1) 1086 typedef struct _FEA /* fea */1087 { 1088 unsigned char fEA; /* flags */ 1089 unsigned char cbName; /* name length not including NULL */ 1090 unsigned short cbValue; /* value length */ 995 typedef struct _FEA 996 { 997 unsigned char fEA; // flags 998 unsigned char cbName; // name length not including NULL 999 unsigned short cbValue; // value length 1091 1000 } FEA; 1092 1001 1093 typedef struct _FEALIST /* feal */1094 { 1095 unsigned long cbList; /* total bytes of structure including full list */ 1096 FEA list[1]; /* variable length FEA structures */ 1002 typedef struct _FEALIST 1003 { 1004 unsigned long cbList; // total bytes of structure including full list 1005 FEA list[1]; // variable length FEA structures 1097 1006 } FEALIST; 1098 1007 #pragma pack() … … 1100 1009 static int unilistea(cli_state * cli, char *fname, void * buffer, unsigned long size) 1101 1010 { 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 } 1154 1155 /* ****************************************************1156 lists EA of a path1157 *******************************************************/1011 int fnum, i; 1012 int gotsize = sizeof(unsigned long); 1013 size_t num_eas; 1014 struct ea_struct *ea_list = NULL; 1015 TALLOC_CTX *mem_ctx; 1016 FEA * p; 1017 FEALIST * pfealist; 1018 char * q; 1019 1020 mem_ctx = talloc_init("%d: ealist", _gettid()); 1021 pfealist = (FEALIST *)buffer; 1022 pfealist->cbList = 0; 1023 1024 if (!NT_STATUS_IS_OK(cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list))) 1025 { 1026 debuglocal(4,"ea_get_file list failed - %s\n", cli_errstr(cli)); 1027 talloc_destroy(mem_ctx); 1028 return os2cli_errno(cli); 1029 } 1030 1031 debuglocal(4,"num_eas = %d\n", num_eas); 1032 1033 // we will count that os/2 max EA size for file is 64kb 1034 p = pfealist->list; 1035 for (i = 0; i < num_eas; i++) 1036 { 1037 int namelen = strlen(ea_list[i].name); 1038 debuglocal(4, "%d Got EA <%s> with namelen %d, size %d. Gross %d. Buf %d\n", i, ea_list[i].name, namelen, ea_list[i].value.length, gotsize, size); 1039 if (namelen > 0xFF || ea_list[i].value.length > 0xFFFF) 1040 { 1041 debuglocal(4, "Skip EA <%s> with namelen %d, size %d\n", ea_list[i].name, namelen, ea_list[i].value.length); 1042 continue; 1043 } 1044 gotsize += sizeof(FEA) + namelen + ea_list[i].value.length + 1; 1045 if (size >= gotsize) 1046 { 1047 p->fEA = 0; 1048 p->cbName = namelen; 1049 p->cbValue = ea_list[i].value.length; 1050 q = (char *)(p + 1); 1051 strncpy(q, ea_list[i].name, namelen + 1); 1052 q += namelen + 1; 1053 memcpy(q, ea_list[i].value.data, ea_list[i].value.length); 1054 p = (FEA *)(q + ea_list[i].value.length); 1055 } 1056 } 1057 pfealist->cbList = gotsize; 1058 debuglocal(4,"ret size = %d\n", gotsize); 1059 1060 talloc_destroy(mem_ctx); 1061 return 0; 1062 } 1063 1064 /* 1065 * lists EA of a path 1066 */ 1158 1067 int _System smbwrp_listea(cli_state * cli, char *fname, void * buffer, unsigned long size) 1159 1068 { 1160 if (!cli || !fname || !buffer) 1161 { 1162 return maperror(EINVAL); 1163 } 1164 1165 debuglocal(4,"EALIst for <%s>\n", fname); 1166 return unilistea(cli, fname, buffer, size); 1167 } 1168 1169 /***************************************************** 1170 lists EA of a file 1171 *******************************************************/ 1069 if (!cli || !fname || !buffer) 1070 return maperror(EINVAL); 1071 1072 debuglocal(4,"EALIst for <%s>\n", fname); 1073 return unilistea(cli, fname, buffer, size); 1074 } 1075 1076 /* 1077 * lists EA of a file 1078 */ 1172 1079 int _System smbwrp_flistea(cli_state * cli, smbwrp_file *file, void * buffer, unsigned long size) 1173 1080 { 1174 if (!cli || !file || !buffer) 1175 { 1176 return maperror(EINVAL); 1177 } 1178 1179 debuglocal(4,"FEALIst for <%s>\n", file->fname); 1180 return unilistea(cli, file->fname, buffer, size); 1181 } 1182 1183 /**************************************************************************** 1184 Check the space on a device. 1185 ****************************************************************************/ 1081 if (!cli || !file || !buffer) 1082 return maperror(EINVAL); 1083 1084 debuglocal(4,"FEALIst for <%s>\n", file->fname); 1085 return unilistea(cli, file->fname, buffer, size); 1086 } 1087 1088 /* 1089 * Check the space on a device. 1090 */ 1186 1091 int _System smbwrp_dskattr(cli_state * cli, FSALLOCATE *pfsa) 1187 1092 { 1188 int total, bsize, avail; 1189 1190 if (!cli || !pfsa) 1191 { 1192 return maperror(EINVAL); 1193 } 1194 1195 if (!NT_STATUS_IS_OK(cli_dskattr(cli, &bsize, &total, &avail))) 1196 { 1197 debuglocal(4,"Error in dskattr: %s\n",cli_errstr(cli)); 1198 return os2cli_errno(cli); 1199 } 1200 1201 debuglocal(4,"\n\t\t%d blocks of size %d. %d blocks available\n", 1202 total, bsize, avail); 1203 1204 // YD currently Samba return it in MB! 1205 pfsa->cSectorUnit = 1; 1206 if (bsize >= 65536) 1207 { 1208 pfsa->cUnit = total*1024; 1209 pfsa->cUnitAvail = avail*1024; 1210 pfsa->cbSector = bsize/1024; 1211 } 1212 else 1213 { 1214 pfsa->cUnit = total; 1215 pfsa->cUnitAvail = avail; 1216 pfsa->cbSector = bsize; 1217 } 1218 1219 return 0; 1220 } 1221 1093 int total, bsize, avail; 1094 1095 if (!cli || !pfsa) 1096 return maperror(EINVAL); 1097 1098 if (!NT_STATUS_IS_OK(cli_dskattr(cli, &bsize, &total, &avail))) 1099 { 1100 debuglocal(4,"Error in dskattr: %s\n",cli_errstr(cli)); 1101 return os2cli_errno(cli); 1102 } 1103 1104 debuglocal(4,"\n\t\t%d blocks of size %d. %d blocks available\n", 1105 total, bsize, avail); 1106 1107 // YD currently Samba return it in MB! 1108 pfsa->cSectorUnit = 1; 1109 if (bsize >= 65536) 1110 { 1111 pfsa->cUnit = total*1024; 1112 pfsa->cUnitAvail = avail*1024; 1113 pfsa->cbSector = bsize/1024; 1114 } 1115 else 1116 { 1117 pfsa->cUnit = total; 1118 pfsa->cUnitAvail = avail; 1119 pfsa->cbSector = bsize; 1120 } 1121 1122 return 0; 1123 }
Note:
See TracChangeset
for help on using the changeset viewer.