Changeset 988 for vendor/current/source3/smbd/service.c
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/smbd/service.c
r860 r988 20 20 #include "includes.h" 21 21 #include "system/filesys.h" 22 #include "system/passwd.h" /* uid_wrapper */ 22 23 #include "../lib/tsocket/tsocket.h" 23 24 #include "smbd/smbd.h" … … 28 29 #include "passdb/lookup_sid.h" 29 30 #include "auth.h" 30 31 extern userdom_struct current_user_info; 31 #include "lib/param/loadparm.h" 32 #include "messages.h" 33 #include "lib/afs/afs_funcs.h" 32 34 33 35 static bool canonicalize_connect_path(connection_struct *conn) … … 61 63 62 64 /* Allocate for strlen + '\0' + possible leading '/' */ 63 destname = (char *) SMB_MALLOC(strlen(connectpath) + 2);65 destname = (char *)talloc_size(conn, strlen(connectpath) + 2); 64 66 if (!destname) { 65 67 return false; … … 160 162 161 163 DEBUG(10,("set_conn_connectpath: service %s, connectpath = %s\n", 162 lp_servicename(SNUM(conn)), destname )); 163 164 string_set(&conn->connectpath, destname); 165 SAFE_FREE(destname); 164 lp_servicename(talloc_tos(), SNUM(conn)), destname )); 165 166 talloc_free(conn->connectpath); 167 conn->connectpath = destname; 168 /* Ensure conn->cwd is initialized - start as conn->connectpath. */ 169 TALLOC_FREE(conn->cwd); 170 conn->cwd = talloc_strdup(conn, conn->connectpath); 171 if (!conn->cwd) { 172 return false; 173 } 166 174 return true; 167 175 } … … 171 179 ****************************************************************************/ 172 180 173 bool set_current_service(connection_struct *conn, uint16 flags, bool do_chdir)181 bool set_current_service(connection_struct *conn, uint16_t flags, bool do_chdir) 174 182 { 175 183 int snum; … … 200 208 201 209 /* Obey the client case sensitivity requests - only for clients that support it. */ 202 switch (lp_case sensitive(snum)) {210 switch (lp_case_sensitive(snum)) { 203 211 case Auto: 204 212 { … … 223 231 } 224 232 225 static int load_registry_service(const char *servicename)226 {227 if (!lp_registry_shares()) {228 return -1;229 }230 231 if ((servicename == NULL) || (*servicename == '\0')) {232 return -1;233 }234 235 if (strequal(servicename, GLOBAL_NAME)) {236 return -2;237 }238 239 if (!process_registry_service(servicename)) {240 return -1;241 }242 243 return lp_servicenumber(servicename);244 }245 246 void load_registry_shares(void)247 {248 DEBUG(8, ("load_registry_shares()\n"));249 if (!lp_registry_shares()) {250 return;251 }252 253 process_registry_shares();254 255 return;256 }257 258 /****************************************************************************259 Add a home service. Returns the new service number or -1 if fail.260 ****************************************************************************/261 262 int add_home_service(const char *service, const char *username, const char *homedir)263 {264 int iHomeService;265 266 if (!service || !homedir || homedir[0] == '\0')267 return -1;268 269 if ((iHomeService = lp_servicenumber(HOMES_NAME)) < 0) {270 if ((iHomeService = load_registry_service(HOMES_NAME)) < 0) {271 return -1;272 }273 }274 275 /*276 * If this is a winbindd provided username, remove277 * the domain component before adding the service.278 * Log a warning if the "path=" parameter does not279 * include any macros.280 */281 282 {283 const char *p = strchr(service,*lp_winbind_separator());284 285 /* We only want the 'user' part of the string */286 if (p) {287 service = p + 1;288 }289 }290 291 if (!lp_add_home(service, iHomeService, username, homedir)) {292 return -1;293 }294 295 return lp_servicenumber(service);296 297 }298 299 /**300 * Find a service entry.301 *302 * @param service is modified (to canonical form??)303 **/304 305 int find_service(TALLOC_CTX *ctx, const char *service_in, char **p_service_out)306 {307 int iService;308 309 if (!service_in) {310 return -1;311 }312 313 /* First make a copy. */314 *p_service_out = talloc_strdup(ctx, service_in);315 if (!*p_service_out) {316 return -1;317 }318 319 all_string_sub(*p_service_out,"\\","/",0);320 321 iService = lp_servicenumber(*p_service_out);322 323 /* now handle the special case of a home directory */324 if (iService < 0) {325 char *phome_dir = get_user_home_dir(ctx, *p_service_out);326 327 if(!phome_dir) {328 /*329 * Try mapping the servicename, it may330 * be a Windows to unix mapped user name.331 */332 if(map_username(ctx, *p_service_out, p_service_out)) {333 if (*p_service_out == NULL) {334 /* Out of memory. */335 return -1;336 }337 phome_dir = get_user_home_dir(338 ctx, *p_service_out);339 }340 }341 342 DEBUG(3,("checking for home directory %s gave %s\n",*p_service_out,343 phome_dir?phome_dir:"(NULL)"));344 345 iService = add_home_service(*p_service_out,*p_service_out /* 'username' */, phome_dir);346 }347 348 /* If we still don't have a service, attempt to add it as a printer. */349 if (iService < 0) {350 int iPrinterService;351 352 if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) < 0) {353 iPrinterService = load_registry_service(PRINTERS_NAME);354 }355 if (iPrinterService >= 0) {356 DEBUG(3,("checking whether %s is a valid printer name...\n",357 *p_service_out));358 if (pcap_printername_ok(*p_service_out)) {359 DEBUG(3,("%s is a valid printer name\n",360 *p_service_out));361 DEBUG(3,("adding %s as a printer service\n",362 *p_service_out));363 lp_add_printer(*p_service_out, iPrinterService);364 iService = lp_servicenumber(*p_service_out);365 if (iService < 0) {366 DEBUG(0,("failed to add %s as a printer service!\n",367 *p_service_out));368 }369 } else {370 DEBUG(3,("%s is not a valid printer name\n",371 *p_service_out));372 }373 }374 }375 376 /* Check for default vfs service? Unsure whether to implement this */377 if (iService < 0) {378 }379 380 if (iService < 0) {381 iService = load_registry_service(*p_service_out);382 }383 384 /* Is it a usershare service ? */385 if (iService < 0 && *lp_usershare_path()) {386 /* Ensure the name is canonicalized. */387 strlower_m(*p_service_out);388 iService = load_usershare_service(*p_service_out);389 }390 391 /* just possibly it's a default service? */392 if (iService < 0) {393 char *pdefservice = lp_defaultservice();394 if (pdefservice &&395 *pdefservice &&396 !strequal(pdefservice, *p_service_out)397 && !strstr_m(*p_service_out,"..")) {398 /*399 * We need to do a local copy here as lp_defaultservice()400 * returns one of the rotating lp_string buffers that401 * could get overwritten by the recursive find_service() call402 * below. Fix from Josef Hinteregger <joehtg@joehtg.co.at>.403 */404 char *defservice = talloc_strdup(ctx, pdefservice);405 406 if (!defservice) {407 goto fail;408 }409 410 /* Disallow anything except explicit share names. */411 if (strequal(defservice,HOMES_NAME) ||412 strequal(defservice, PRINTERS_NAME) ||413 strequal(defservice, "IPC$")) {414 TALLOC_FREE(defservice);415 goto fail;416 }417 418 iService = find_service(ctx, defservice, p_service_out);419 if (!*p_service_out) {420 TALLOC_FREE(defservice);421 iService = -1;422 goto fail;423 }424 if (iService >= 0) {425 all_string_sub(*p_service_out, "_","/",0);426 iService = lp_add_service(*p_service_out, iService);427 }428 TALLOC_FREE(defservice);429 }430 }431 432 if (iService >= 0) {433 if (!VALID_SNUM(iService)) {434 DEBUG(0,("Invalid snum %d for %s\n",iService,435 *p_service_out));436 iService = -1;437 }438 }439 440 fail:441 442 if (iService < 0) {443 DEBUG(3,("find_service() failed to find service %s\n",444 *p_service_out));445 }446 447 return (iService);448 }449 450 451 233 /**************************************************************************** 452 234 do some basic sainity checks on the share. … … 454 236 ****************************************************************************/ 455 237 456 static NTSTATUS share_sanity_checks(struct client_address *client_id, int snum, 238 static NTSTATUS share_sanity_checks(const struct tsocket_address *remote_address, 239 const char *rhost, 240 int snum, 457 241 fstring dev) 458 242 { 459 if (!lp_snum_ok(snum) || 460 !allow_access(lp_hostsdeny(snum), lp_hostsallow(snum), 461 client_id->name, client_id->addr)) { 243 char *raddr; 244 245 raddr = tsocket_address_inet_addr_string(remote_address, 246 talloc_tos()); 247 if (raddr == NULL) { 248 return NT_STATUS_NO_MEMORY; 249 } 250 251 if (!lp_snum_ok(snum) || 252 !allow_access(lp_hosts_deny(snum), lp_hosts_allow(snum), 253 rhost, raddr)) { 462 254 return NT_STATUS_ACCESS_DENIED; 463 255 } 464 256 465 257 if (dev[0] == '?' || !dev[0]) { 466 if (lp_print _ok(snum)) {258 if (lp_printable(snum)) { 467 259 fstrcpy(dev,"LPT1:"); 468 260 } else if (strequal(lp_fstype(snum), "IPC")) { … … 473 265 } 474 266 475 strupper_m(dev); 476 477 if (lp_print_ok(snum)) { 267 if (!strupper_m(dev)) { 268 DEBUG(2,("strupper_m %s failed\n", dev)); 269 return NT_STATUS_INVALID_PARAMETER; 270 } 271 272 if (lp_printable(snum)) { 478 273 if (!strequal(dev, "LPT1:")) { 479 274 return NT_STATUS_BAD_DEVICE_TYPE; … … 488 283 489 284 /* Behave as a printer if we are supposed to */ 490 if (lp_print _ok(snum) && (strcmp(dev, "A:") == 0)) {285 if (lp_printable(snum) && (strcmp(dev, "A:") == 0)) { 491 286 fstrcpy(dev, "LPT1:"); 492 287 } … … 515 310 gid_t gid; 516 311 517 groupname = talloc_strdup(talloc_tos(), lp_force_group(snum));312 groupname = lp_force_group(talloc_tos(), snum); 518 313 if (groupname == NULL) { 519 314 DEBUG(1, ("talloc_strdup failed\n")); … … 528 323 529 324 groupname = talloc_string_sub(talloc_tos(), groupname, 530 "%S", lp_servicename( snum));325 "%S", lp_servicename(talloc_tos(), snum)); 531 326 if (groupname == NULL) { 532 327 DEBUG(1, ("talloc_string_sub failed\n")); … … 589 384 590 385 /**************************************************************************** 591 Create an auth_se rversupplied_info structure for a connection_struct386 Create an auth_session_info structure for a connection_struct 592 387 ****************************************************************************/ 593 388 594 389 static NTSTATUS create_connection_session_info(struct smbd_server_connection *sconn, 595 390 TALLOC_CTX *mem_ctx, int snum, 596 struct auth_serversupplied_info *vuid_serverinfo, 597 DATA_BLOB password, 598 struct auth_serversupplied_info **presult) 391 struct auth_session_info *session_info, 392 struct auth_session_info **presult) 599 393 { 394 struct auth_session_info *result; 395 600 396 if (lp_guest_only(snum)) { 601 return make_se rver_info_guest(mem_ctx, presult);397 return make_session_info_guest(mem_ctx, presult); 602 398 } 603 399 604 if (vuid_serverinfo != NULL) { 605 606 struct auth_serversupplied_info *result; 607 608 /* 609 * This is the normal security != share case where we have a 610 * valid vuid from the session setup. */ 611 612 if (vuid_serverinfo->guest) { 613 if (!lp_guest_ok(snum)) { 614 DEBUG(2, ("guest user (from session setup) " 615 "not permitted to access this share " 616 "(%s)\n", lp_servicename(snum))); 617 return NT_STATUS_ACCESS_DENIED; 618 } 619 } else { 620 if (!user_ok_token(vuid_serverinfo->unix_name, 621 vuid_serverinfo->info3->base.domain.string, 622 vuid_serverinfo->security_token, snum)) { 623 DEBUG(2, ("user '%s' (from session setup) not " 624 "permitted to access this share " 625 "(%s)\n", 626 vuid_serverinfo->unix_name, 627 lp_servicename(snum))); 628 return NT_STATUS_ACCESS_DENIED; 629 } 630 } 631 632 result = copy_serverinfo(mem_ctx, vuid_serverinfo); 633 if (result == NULL) { 634 return NT_STATUS_NO_MEMORY; 635 } 636 637 *presult = result; 638 return NT_STATUS_OK; 639 } 640 641 if (lp_security() == SEC_SHARE) { 642 643 fstring user; 644 bool guest; 645 646 /* add the sharename as a possible user name if we 647 are in share mode security */ 648 649 add_session_user(sconn, lp_servicename(snum)); 650 651 /* shall we let them in? */ 652 653 if (!authorise_login(sconn, snum,user,password,&guest)) { 654 DEBUG( 2, ( "Invalid username/password for [%s]\n", 655 lp_servicename(snum)) ); 656 return NT_STATUS_WRONG_PASSWORD; 657 } 658 659 return make_serverinfo_from_username(mem_ctx, user, guest, guest, 660 presult); 661 } 662 663 DEBUG(0, ("invalid VUID (vuser) but not in security=share\n")); 664 return NT_STATUS_ACCESS_DENIED; 400 /* 401 * This is the normal security != share case where we have a 402 * valid vuid from the session setup. */ 403 404 if (security_session_user_level(session_info, NULL) < SECURITY_USER) { 405 if (!lp_guest_ok(snum)) { 406 DEBUG(2, ("guest user (from session setup) " 407 "not permitted to access this share " 408 "(%s)\n", lp_servicename(talloc_tos(), snum))); 409 return NT_STATUS_ACCESS_DENIED; 410 } 411 } else { 412 if (!user_ok_token(session_info->unix_info->unix_name, 413 session_info->info->domain_name, 414 session_info->security_token, snum)) { 415 DEBUG(2, ("user '%s' (from session setup) not " 416 "permitted to access this share " 417 "(%s)\n", 418 session_info->unix_info->unix_name, 419 lp_servicename(talloc_tos(), snum))); 420 return NT_STATUS_ACCESS_DENIED; 421 } 422 } 423 424 result = copy_session_info(mem_ctx, session_info); 425 if (result == NULL) { 426 return NT_STATUS_NO_MEMORY; 427 } 428 429 *presult = result; 430 return NT_STATUS_OK; 665 431 } 666 432 667 433 /**************************************************************************** 668 set relavent user and group settings corresponding to force user/group434 Set relevant user and group settings corresponding to force user/group 669 435 configuration for the given snum. 670 436 ****************************************************************************/ … … 674 440 NTSTATUS status; 675 441 676 if (*lp_force_user( snum)) {442 if (*lp_force_user(talloc_tos(), snum)) { 677 443 678 444 /* … … 682 448 683 449 char *fuser; 684 struct auth_serversupplied_info *forced_serverinfo; 685 686 fuser = talloc_string_sub(conn, lp_force_user(snum), "%S", 450 char *sanitized_username; 451 struct auth_session_info *forced_serverinfo; 452 bool guest; 453 454 fuser = talloc_string_sub(conn, lp_force_user(talloc_tos(), snum), "%S", 687 455 lp_const_servicename(snum)); 688 456 if (fuser == NULL) { … … 690 458 } 691 459 692 status = make_serverinfo_from_username( 693 conn, fuser, false, conn->session_info->guest, 460 guest = security_session_user_level(conn->session_info, NULL) < SECURITY_USER; 461 462 status = make_session_info_from_username( 463 conn, fuser, 464 guest, 694 465 &forced_serverinfo); 695 466 if (!NT_STATUS_IS_OK(status)) { … … 700 471 as it is the original user given in the connect attempt. 701 472 This is used in '%U' substitutions. */ 702 TALLOC_FREE(forced_serverinfo->sanitized_username); 703 forced_serverinfo->sanitized_username = 704 talloc_move(forced_serverinfo, 705 &conn->session_info->sanitized_username); 473 sanitized_username = discard_const_p(char, 474 forced_serverinfo->unix_info->sanitized_username); 475 TALLOC_FREE(sanitized_username); 476 forced_serverinfo->unix_info->sanitized_username = 477 talloc_move(forced_serverinfo->unix_info, 478 &conn->session_info->unix_info->sanitized_username); 706 479 707 480 TALLOC_FREE(conn->session_info); … … 717 490 */ 718 491 719 if (*lp_force_group( snum)) {492 if (*lp_force_group(talloc_tos(), snum)) { 720 493 721 494 status = find_forced_group( 722 conn->force_user, snum, conn->session_info->unix_ name,495 conn->force_user, snum, conn->session_info->unix_info->unix_name, 723 496 &conn->session_info->security_token->sids[1], 724 &conn->session_info->u tok.gid);497 &conn->session_info->unix_token->gid); 725 498 726 499 if (!NT_STATUS_IS_OK(status)) { … … 734 507 * "force_user" was set. 735 508 */ 736 conn->force_group_gid = conn->session_info->u tok.gid;509 conn->force_group_gid = conn->session_info->unix_token->gid; 737 510 } 738 511 739 512 return NT_STATUS_OK; 740 }741 742 /****************************************************************************743 Setup the share access mask for a connection.744 ****************************************************************************/745 746 static void create_share_access_mask(connection_struct *conn, int snum)747 {748 const struct security_token *token = conn->session_info->security_token;749 750 share_access_check(token,751 lp_servicename(snum),752 MAXIMUM_ALLOWED_ACCESS,753 &conn->share_access);754 755 if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) {756 conn->share_access |= SEC_FLAG_SYSTEM_SECURITY;757 }758 if (security_token_has_privilege(token, SEC_PRIV_RESTORE)) {759 conn->share_access |= (SEC_RIGHTS_PRIV_RESTORE);760 }761 if (security_token_has_privilege(token, SEC_PRIV_BACKUP)) {762 conn->share_access |= (SEC_RIGHTS_PRIV_BACKUP);763 }764 if (security_token_has_privilege(token, SEC_PRIV_TAKE_OWNERSHIP)) {765 conn->share_access |= (SEC_STD_WRITE_OWNER);766 }767 513 } 768 514 … … 772 518 ****************************************************************************/ 773 519 774 static connection_struct *make_connection_snum(struct smbd_server_connection *sconn,520 static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn, 775 521 connection_struct *conn, 776 int snum, user_struct *vuser, 777 DATA_BLOB password, 778 const char *pdev, 779 NTSTATUS *pstatus) 522 int snum, struct user_struct *vuser, 523 const char *pdev) 780 524 { 525 struct smbd_server_connection *sconn = xconn->client->sconn; 781 526 struct smb_filename *smb_fname_cpath = NULL; 782 527 fstring dev; 783 528 int ret; 784 529 bool on_err_call_dis_hook = false; 785 bool claimed_connection = false;786 530 uid_t effuid; 787 531 gid_t effgid; … … 790 534 fstrcpy(dev, pdev); 791 535 792 *pstatus = share_sanity_checks(&sconn->client_id, snum, dev); 793 if (NT_STATUS_IS_ERR(*pstatus)) { 536 status = share_sanity_checks(sconn->remote_address, 537 sconn->remote_hostname, 538 snum, 539 dev); 540 if (NT_STATUS_IS_ERR(status)) { 794 541 goto err_root_exit; 795 542 } … … 798 545 799 546 status = create_connection_session_info(sconn, 800 conn, snum, vuser ? vuser->session_info : NULL, password,547 conn, snum, vuser->session_info, 801 548 &conn->session_info); 802 549 … … 804 551 DEBUG(1, ("create_connection_session_info failed: %s\n", 805 552 nt_errstr(status))); 806 *pstatus = status;807 553 goto err_root_exit; 808 554 } 809 555 810 if ( (lp_guest_only(snum)) || (lp_security() == SEC_SHARE)) {556 if (lp_guest_only(snum)) { 811 557 conn->force_user = true; 812 558 } 813 814 add_session_user(sconn, conn->session_info->unix_name);815 559 816 560 conn->num_files_open = 0; 817 561 conn->lastused = conn->lastused_count = time(NULL); 818 conn->used = True;819 562 conn->printer = (strncmp(dev,"LPT",3) == 0); 820 563 conn->ipc = ( (strncmp(dev,"IPC",3) == 0) || … … 822 565 823 566 /* Case options for the share. */ 824 if (lp_case sensitive(snum) == Auto) {567 if (lp_case_sensitive(snum) == Auto) { 825 568 /* We will be setting this per packet. Set to be case 826 569 * insensitive for now. */ 827 570 conn->case_sensitive = False; 828 571 } else { 829 conn->case_sensitive = (bool)lp_case sensitive(snum);830 } 831 832 conn->case_preserve = lp_preserve case(snum);833 conn->short_case_preserve = lp_short preservecase(snum);572 conn->case_sensitive = (bool)lp_case_sensitive(snum); 573 } 574 575 conn->case_preserve = lp_preserve_case(snum); 576 conn->short_case_preserve = lp_short_preserve_case(snum); 834 577 835 578 conn->encrypt_level = lp_smb_encrypt(snum); … … 840 583 conn->aio_write_behind_list = NULL; 841 584 842 conn->read_only = lp_read only(SNUM(conn));585 conn->read_only = lp_read_only(SNUM(conn)); 843 586 844 587 status = set_conn_force_user_group(conn, snum); 845 588 if (!NT_STATUS_IS_OK(status)) { 846 *pstatus = status; 847 return NULL; 848 } 849 850 conn->vuid = (vuser != NULL) ? vuser->vuid : UID_FIELD_INVALID; 589 goto err_root_exit; 590 } 591 592 conn->vuid = vuser->vuid; 851 593 852 594 { 853 595 char *s = talloc_sub_advanced(talloc_tos(), 854 lp_servicename( SNUM(conn)),855 conn->session_info->unix_ name,596 lp_servicename(talloc_tos(), SNUM(conn)), 597 conn->session_info->unix_info->unix_name, 856 598 conn->connectpath, 857 conn->session_info->u tok.gid,858 conn->session_info-> sanitized_username,859 conn->session_info->info 3->base.domain.string,860 lp_path name(snum));599 conn->session_info->unix_token->gid, 600 conn->session_info->unix_info->sanitized_username, 601 conn->session_info->info->domain_name, 602 lp_path(talloc_tos(), snum)); 861 603 if (!s) { 862 *pstatus = NT_STATUS_NO_MEMORY;604 status = NT_STATUS_NO_MEMORY; 863 605 goto err_root_exit; 864 606 } … … 866 608 if (!set_conn_connectpath(conn,s)) { 867 609 TALLOC_FREE(s); 868 *pstatus = NT_STATUS_NO_MEMORY;610 status = NT_STATUS_NO_MEMORY; 869 611 goto err_root_exit; 870 612 } 871 613 DEBUG(3,("Connect path is '%s' for service [%s]\n",s, 872 lp_servicename( snum)));614 lp_servicename(talloc_tos(), snum))); 873 615 TALLOC_FREE(s); 874 616 } 875 617 876 618 /* 877 * New code to check if there's a share security descripter 878 * added from NT server manager. This is done after the 879 * smb.conf checks are done as we need a uid and token. JRA. 619 * Set up the share security descriptor. 620 * NOTE - we use the *INCOMING USER* session_info 621 * here, as does (indirectly) change_to_user(), 622 * which can be called on any incoming packet. 623 * This way we set up the share access based 624 * on the authenticated user, not the forced 625 * user. See bug: 880 626 * 627 * https://bugzilla.samba.org/show_bug.cgi?id=9878 881 628 */ 882 629 883 create_share_access_mask(conn, snum); 884 885 if ((conn->share_access & FILE_WRITE_DATA) == 0) { 886 if ((conn->share_access & FILE_READ_DATA) == 0) { 887 /* No access, read or write. */ 888 DEBUG(0,("make_connection: connection to %s " 889 "denied due to security " 890 "descriptor.\n", 891 lp_servicename(snum))); 892 *pstatus = NT_STATUS_ACCESS_DENIED; 893 goto err_root_exit; 894 } else { 895 conn->read_only = True; 896 } 897 } 630 status = check_user_share_access(conn, 631 vuser->session_info, 632 &conn->share_access, 633 &conn->read_only); 634 if (!NT_STATUS_IS_OK(status)) { 635 goto err_root_exit; 636 } 637 898 638 /* Initialise VFS function pointers */ 899 639 900 640 if (!smbd_vfs_init(conn)) { 901 641 DEBUG(0, ("vfs_init failed for service %s\n", 902 lp_servicename( snum)));903 *pstatus = NT_STATUS_BAD_NETWORK_NAME;642 lp_servicename(talloc_tos(), snum))); 643 status = NT_STATUS_BAD_NETWORK_NAME; 904 644 goto err_root_exit; 905 645 } … … 915 655 916 656 if ((lp_max_connections(snum) > 0) 917 && (count_current_connections(lp_servicename( SNUM(conn)), True) >=657 && (count_current_connections(lp_servicename(talloc_tos(), SNUM(conn)), True) >= 918 658 lp_max_connections(snum))) { 919 659 920 660 DEBUG(1, ("Max connections (%d) exceeded for %s\n", 921 lp_max_connections(snum), lp_servicename(snum))); 922 *pstatus = NT_STATUS_INSUFFICIENT_RESOURCES; 661 lp_max_connections(snum), 662 lp_servicename(talloc_tos(), snum))); 663 status = NT_STATUS_INSUFFICIENT_RESOURCES; 923 664 goto err_root_exit; 924 665 } 925 926 /*927 * Get us an entry in the connections db928 */929 if (!claim_connection(conn, lp_servicename(snum))) {930 DEBUG(1, ("Could not store connections entry\n"));931 *pstatus = NT_STATUS_INTERNAL_DB_ERROR;932 goto err_root_exit;933 }934 claimed_connection = true;935 666 936 667 /* Invoke VFS make connection hook - this must be the first 937 668 filesystem operation that we do. */ 938 669 939 if (SMB_VFS_CONNECT(conn, lp_servicename(snum), 940 conn->session_info->unix_name) < 0) { 941 DEBUG(0,("make_connection: VFS make connection failed!\n")); 942 *pstatus = NT_STATUS_UNSUCCESSFUL; 670 if (SMB_VFS_CONNECT(conn, lp_servicename(talloc_tos(), snum), 671 conn->session_info->unix_info->unix_name) < 0) { 672 DBG_WARNING("SMB_VFS_CONNECT for service '%s' at '%s' failed: %s\n", 673 lp_servicename(talloc_tos(), snum), conn->connectpath, 674 strerror(errno)); 675 status = NT_STATUS_UNSUCCESSFUL; 943 676 goto err_root_exit; 944 677 } … … 947 680 on_err_call_dis_hook = true; 948 681 949 if ((!conn->printer) && (!conn->ipc)) { 950 conn->notify_ctx = notify_init(conn, 951 sconn_server_id(sconn), 952 sconn->msg_ctx, 953 smbd_event_context(), 954 conn); 682 if ((!conn->printer) && (!conn->ipc) && 683 lp_change_notify()) { 684 if (sconn->notify_ctx == NULL) { 685 sconn->notify_ctx = notify_init( 686 sconn, sconn->msg_ctx, sconn->ev_ctx); 687 status = messaging_register( 688 sconn->msg_ctx, sconn, 689 MSG_SMB_NOTIFY_CANCEL_DELETED, 690 smbd_notify_cancel_deleted); 691 } 692 if (sconn->sys_notify_ctx == NULL) { 693 sconn->sys_notify_ctx = sys_notify_context_create( 694 sconn, sconn->ev_ctx); 695 } 696 } 697 698 if (lp_kernel_oplocks(snum)) { 699 init_kernel_oplocks(conn->sconn); 955 700 } 956 701 … … 970 715 * to below */ 971 716 /* execute any "root preexec = " line */ 972 if (*lp_root preexec(snum)) {717 if (*lp_root_preexec(talloc_tos(), snum)) { 973 718 char *cmd = talloc_sub_advanced(talloc_tos(), 974 lp_servicename( SNUM(conn)),975 conn->session_info->unix_ name,719 lp_servicename(talloc_tos(), SNUM(conn)), 720 conn->session_info->unix_info->unix_name, 976 721 conn->connectpath, 977 conn->session_info->u tok.gid,978 conn->session_info-> sanitized_username,979 conn->session_info->info 3->base.domain.string,980 lp_root preexec(snum));722 conn->session_info->unix_token->gid, 723 conn->session_info->unix_info->sanitized_username, 724 conn->session_info->info->domain_name, 725 lp_root_preexec(talloc_tos(), snum)); 981 726 DEBUG(5,("cmd=%s\n",cmd)); 982 727 ret = smbrun(cmd,NULL); 983 728 TALLOC_FREE(cmd); 984 if (ret != 0 && lp_root preexec_close(snum)) {729 if (ret != 0 && lp_root_preexec_close(snum)) { 985 730 DEBUG(1,("root preexec gave %d - failing " 986 731 "connection\n", ret)); 987 *pstatus = NT_STATUS_ACCESS_DENIED;732 status = NT_STATUS_ACCESS_DENIED; 988 733 goto err_root_exit; 989 734 } … … 994 739 /* No point continuing if they fail the basic checks */ 995 740 DEBUG(0,("Can't become connected user!\n")); 996 *pstatus = NT_STATUS_LOGON_FAILURE;741 status = NT_STATUS_LOGON_FAILURE; 997 742 goto err_root_exit; 998 743 } … … 1008 753 1009 754 /* execute any "preexec = " line */ 1010 if (*lp_preexec( snum)) {755 if (*lp_preexec(talloc_tos(), snum)) { 1011 756 char *cmd = talloc_sub_advanced(talloc_tos(), 1012 lp_servicename( SNUM(conn)),1013 conn->session_info->unix_ name,757 lp_servicename(talloc_tos(), SNUM(conn)), 758 conn->session_info->unix_info->unix_name, 1014 759 conn->connectpath, 1015 conn->session_info->u tok.gid,1016 conn->session_info-> sanitized_username,1017 conn->session_info->info 3->base.domain.string,1018 lp_preexec( snum));760 conn->session_info->unix_token->gid, 761 conn->session_info->unix_info->sanitized_username, 762 conn->session_info->info->domain_name, 763 lp_preexec(talloc_tos(), snum)); 1019 764 ret = smbrun(cmd,NULL); 1020 765 TALLOC_FREE(cmd); … … 1022 767 DEBUG(1,("preexec gave %d - failing connection\n", 1023 768 ret)); 1024 *pstatus = NT_STATUS_ACCESS_DENIED;769 status = NT_STATUS_ACCESS_DENIED; 1025 770 goto err_root_exit; 1026 771 } … … 1052 797 DEBUG(0, ("canonicalize_connect_path failed " 1053 798 "for service %s, path %s\n", 1054 lp_servicename( snum),799 lp_servicename(talloc_tos(), snum), 1055 800 conn->connectpath)); 1056 *pstatus = NT_STATUS_BAD_NETWORK_NAME;801 status = NT_STATUS_BAD_NETWORK_NAME; 1057 802 goto err_root_exit; 1058 803 } … … 1061 806 /* Add veto/hide lists */ 1062 807 if (!IS_IPC(conn) && !IS_PRINT(conn)) { 1063 set_namearray( &conn->veto_list, lp_veto_files(snum)); 1064 set_namearray( &conn->hide_list, lp_hide_files(snum)); 1065 set_namearray( &conn->veto_oplock_list, lp_veto_oplocks(snum)); 808 set_namearray( &conn->veto_list, 809 lp_veto_files(talloc_tos(), snum)); 810 set_namearray( &conn->hide_list, 811 lp_hide_files(talloc_tos(), snum)); 812 set_namearray( &conn->veto_oplock_list, 813 lp_veto_oplock_files(talloc_tos(), snum)); 1066 814 set_namearray( &conn->aio_write_behind_list, 1067 lp_aio_write_behind( snum));1068 } 1069 s tatus = create_synthetic_smb_fname(talloc_tos(), conn->connectpath,1070 NULL, NULL, &smb_fname_cpath);1071 if ( !NT_STATUS_IS_OK(status)) {1072 *pstatus = status;815 lp_aio_write_behind(talloc_tos(), snum)); 816 } 817 smb_fname_cpath = synthetic_smb_fname(talloc_tos(), conn->connectpath, 818 NULL, NULL); 819 if (smb_fname_cpath == NULL) { 820 status = NT_STATUS_NO_MEMORY; 1073 821 goto err_root_exit; 1074 822 } … … 1085 833 DEBUG(0,("'%s' is not a directory, when connecting to " 1086 834 "[%s]\n", conn->connectpath, 1087 lp_servicename( snum)));835 lp_servicename(talloc_tos(), snum))); 1088 836 } else { 1089 837 DEBUG(0,("'%s' does not exist or permission denied " 1090 838 "when connecting to [%s] Error was %s\n", 1091 conn->connectpath, lp_servicename(snum), 839 conn->connectpath, 840 lp_servicename(talloc_tos(), snum), 1092 841 strerror(errno) )); 1093 842 } 1094 *pstatus = NT_STATUS_BAD_NETWORK_NAME;843 status = NT_STATUS_BAD_NETWORK_NAME; 1095 844 goto err_root_exit; 1096 845 } 1097 846 conn->base_share_dev = smb_fname_cpath->st.st_ex_dev; 1098 847 1099 string_set(&conn->origpath,conn->connectpath); 848 talloc_free(conn->origpath); 849 conn->origpath = talloc_strdup(conn, conn->connectpath); 1100 850 1101 851 /* Figure out the characteristics of the underlying filesystem. This … … 1112 862 */ 1113 863 1114 if( DEBUGLVL( IS_IPC(conn) ? 3 : 1) ) {864 if( DEBUGLVL( IS_IPC(conn) ? 3 : 2 ) ) { 1115 865 dbgtext( "%s (%s) ", get_remote_machine_name(), 1116 conn->sconn->client_id.addr ); 1117 dbgtext( "%s", srv_is_signing_active(sconn) ? "signed " : ""); 1118 dbgtext( "connect to service %s ", lp_servicename(snum) ); 866 tsocket_address_string(conn->sconn->remote_address, 867 talloc_tos()) ); 868 dbgtext( "%s", srv_is_signing_active(xconn) ? "signed " : ""); 869 dbgtext( "connect to service %s ", 870 lp_servicename(talloc_tos(), snum) ); 1119 871 dbgtext( "initially as user %s ", 1120 conn->session_info->unix_ name );872 conn->session_info->unix_info->unix_name ); 1121 873 dbgtext( "(uid=%d, gid=%d) ", (int)effuid, (int)effgid ); 1122 dbgtext( "(pid %d)\n", (int) sys_getpid() );1123 } 1124 1125 return (conn);874 dbgtext( "(pid %d)\n", (int)getpid() ); 875 } 876 877 return status; 1126 878 1127 879 err_root_exit: 880 1128 881 TALLOC_FREE(smb_fname_cpath); 1129 882 /* We must exit this function as root. */ … … 1135 888 SMB_VFS_DISCONNECT(conn); 1136 889 } 1137 if (claimed_connection) { 1138 yield_connection(conn, lp_servicename(snum)); 1139 } 1140 return NULL; 890 return status; 1141 891 } 1142 892 … … 1145 895 ****************************************************************************/ 1146 896 1147 static connection_struct *make_connection_smb1(struct smb d_server_connection *sconn,1148 int snum, user_struct *vuser,1149 DATA_BLOB password,897 static connection_struct *make_connection_smb1(struct smb_request *req, 898 NTTIME now, 899 int snum, struct user_struct *vuser, 1150 900 const char *pdev, 1151 901 NTSTATUS *pstatus) 1152 902 { 1153 connection_struct *ret_conn = NULL; 1154 connection_struct *conn = conn_new(sconn); 903 struct smbXsrv_tcon *tcon; 904 NTSTATUS status; 905 struct connection_struct *conn; 906 907 status = smb1srv_tcon_create(req->xconn, now, &tcon); 908 if (!NT_STATUS_IS_OK(status)) { 909 DEBUG(0,("make_connection_smb1: Couldn't find free tcon %s.\n", 910 nt_errstr(status))); 911 *pstatus = status; 912 return NULL; 913 } 914 915 conn = conn_new(req->sconn); 1155 916 if (!conn) { 917 TALLOC_FREE(tcon); 918 1156 919 DEBUG(0,("make_connection_smb1: Couldn't find free connection.\n")); 1157 920 *pstatus = NT_STATUS_INSUFFICIENT_RESOURCES; 1158 921 return NULL; 1159 922 } 1160 ret_conn = make_connection_snum(sconn, 923 924 conn->cnum = tcon->global->tcon_wire_id; 925 conn->tcon = tcon; 926 927 *pstatus = make_connection_snum(req->xconn, 1161 928 conn, 1162 929 snum, 1163 930 vuser, 1164 password, 1165 pdev, 1166 pstatus); 1167 if (ret_conn != conn) { 931 pdev); 932 if (!NT_STATUS_IS_OK(*pstatus)) { 1168 933 conn_free(conn); 1169 return NULL; 1170 } 1171 return conn; 934 TALLOC_FREE(tcon); 935 return NULL; 936 } 937 938 tcon->global->share_name = lp_servicename(tcon->global, SNUM(conn)); 939 if (tcon->global->share_name == NULL) { 940 conn_free(conn); 941 TALLOC_FREE(tcon); 942 *pstatus = NT_STATUS_NO_MEMORY; 943 return NULL; 944 } 945 tcon->global->session_global_id = 946 vuser->session->global->session_global_id; 947 948 tcon->compat = talloc_move(tcon, &conn); 949 tcon->status = NT_STATUS_OK; 950 951 *pstatus = smbXsrv_tcon_update(tcon); 952 if (!NT_STATUS_IS_OK(*pstatus)) { 953 TALLOC_FREE(tcon); 954 return NULL; 955 } 956 957 return tcon->compat; 1172 958 } 1173 959 … … 1177 963 ****************************************************************************/ 1178 964 1179 connection_struct *make_connection_smb2(struct smbd_s erver_connection *sconn,1180 struct smb d_smb2_tcon *tcon,1181 user_struct *vuser,1182 DATA_BLOB password,965 connection_struct *make_connection_smb2(struct smbd_smb2_request *req, 966 struct smbXsrv_tcon *tcon, 967 int snum, 968 struct user_struct *vuser, 1183 969 const char *pdev, 1184 970 NTSTATUS *pstatus) 1185 971 { 1186 connection_struct *ret_conn = NULL;972 struct smbd_server_connection *sconn = req->sconn; 1187 973 connection_struct *conn = conn_new(sconn); 1188 974 if (!conn) { … … 1191 977 return NULL; 1192 978 } 1193 conn->cnum = tcon->tid; 1194 ret_conn = make_connection_snum(sconn, 979 980 conn->cnum = tcon->global->tcon_wire_id; 981 conn->tcon = tcon; 982 983 *pstatus = make_connection_snum(req->xconn, 1195 984 conn, 1196 tcon->snum,985 snum, 1197 986 vuser, 1198 password, 1199 pdev, 1200 pstatus); 1201 if (ret_conn != conn) { 987 pdev); 988 if (!NT_STATUS_IS_OK(*pstatus)) { 1202 989 conn_free(conn); 1203 990 return NULL; … … 1212 999 ****************************************************************************/ 1213 1000 1214 connection_struct *make_connection(struct smbd_server_connection *sconn, 1215 const char *service_in, DATA_BLOB password, 1216 const char *pdev, uint16 vuid, 1001 connection_struct *make_connection(struct smb_request *req, 1002 NTTIME now, 1003 const char *service_in, 1004 const char *pdev, uint64_t vuid, 1217 1005 NTSTATUS *status) 1218 1006 { 1007 struct smbd_server_connection *sconn = req->sconn; 1219 1008 uid_t euid; 1220 user_struct *vuser = NULL;1009 struct user_struct *vuser = NULL; 1221 1010 char *service = NULL; 1222 1011 fstring dev; … … 1238 1027 } 1239 1028 1240 if(lp_security() != SEC_SHARE) { 1241 vuser = get_valid_user_struct(sconn, vuid); 1242 if (!vuser) { 1243 DEBUG(1,("make_connection: refusing to connect with " 1244 "no session setup\n")); 1245 *status = NT_STATUS_ACCESS_DENIED; 1246 return NULL; 1247 } 1029 vuser = get_valid_user_struct(sconn, vuid); 1030 if (!vuser) { 1031 DEBUG(1,("make_connection: refusing to connect with " 1032 "no session setup\n")); 1033 *status = NT_STATUS_ACCESS_DENIED; 1034 return NULL; 1248 1035 } 1249 1036 … … 1258 1045 1259 1046 if (strequal(service_in,HOMES_NAME)) { 1260 if(lp_security() != SEC_SHARE) { 1261 DATA_BLOB no_pw = data_blob_null; 1262 if (vuser->homes_snum == -1) { 1263 DEBUG(2, ("[homes] share not available for " 1264 "this user because it was not found " 1265 "or created at session setup " 1266 "time\n")); 1267 *status = NT_STATUS_BAD_NETWORK_NAME; 1268 return NULL; 1269 } 1270 DEBUG(5, ("making a connection to [homes] service " 1271 "created at session setup time\n")); 1272 return make_connection_smb1(sconn, 1273 vuser->homes_snum, 1274 vuser, no_pw, 1275 dev, status); 1276 } else { 1277 /* Security = share. Try with 1278 * current_user_info.smb_name as the username. */ 1279 if (*current_user_info.smb_name) { 1280 char *unix_username = NULL; 1281 (void)map_username(talloc_tos(), 1282 current_user_info.smb_name, 1283 &unix_username); 1284 snum = find_service(talloc_tos(), 1285 unix_username, 1286 &unix_username); 1287 if (!unix_username) { 1288 *status = NT_STATUS_NO_MEMORY; 1289 } 1290 return NULL; 1291 } 1292 if (snum != -1) { 1293 DEBUG(5, ("making a connection to 'homes' " 1294 "service %s based on " 1295 "security=share\n", service_in)); 1296 return make_connection_smb1(sconn, 1297 snum, NULL, 1298 password, 1299 dev, status); 1300 } 1301 } 1302 } else if ((lp_security() != SEC_SHARE) && (vuser->homes_snum != -1) 1047 if (vuser->homes_snum == -1) { 1048 DEBUG(2, ("[homes] share not available for " 1049 "this user because it was not found " 1050 "or created at session setup " 1051 "time\n")); 1052 *status = NT_STATUS_BAD_NETWORK_NAME; 1053 return NULL; 1054 } 1055 DEBUG(5, ("making a connection to [homes] service " 1056 "created at session setup time\n")); 1057 return make_connection_smb1(req, now, 1058 vuser->homes_snum, 1059 vuser, 1060 dev, status); 1061 } else if ((vuser->homes_snum != -1) 1303 1062 && strequal(service_in, 1304 lp_servicename(vuser->homes_snum))) { 1305 DATA_BLOB no_pw = data_blob_null; 1063 lp_servicename(talloc_tos(), vuser->homes_snum))) { 1306 1064 DEBUG(5, ("making a connection to 'homes' service [%s] " 1307 1065 "created at session setup time\n", service_in)); 1308 return make_connection_smb1( sconn,1066 return make_connection_smb1(req, now, 1309 1067 vuser->homes_snum, 1310 vuser, no_pw,1068 vuser, 1311 1069 dev, status); 1312 1070 } … … 1318 1076 } 1319 1077 1320 strlower_m(service); 1078 if (!strlower_m(service)) { 1079 DEBUG(2, ("strlower_m %s failed\n", service)); 1080 *status = NT_STATUS_INVALID_PARAMETER; 1081 return NULL; 1082 } 1321 1083 1322 1084 snum = find_service(talloc_tos(), service, &service); … … 1344 1106 1345 1107 /* Handle non-Dfs clients attempting connections to msdfs proxy */ 1346 if (lp_host_msdfs() && (*lp_msdfs_proxy( snum) != '\0')) {1108 if (lp_host_msdfs() && (*lp_msdfs_proxy(talloc_tos(), snum) != '\0')) { 1347 1109 DEBUG(3, ("refusing connection to dfs proxy share '%s' " 1348 1110 "(pointing to %s)\n", 1349 service, lp_msdfs_proxy( snum)));1111 service, lp_msdfs_proxy(talloc_tos(), snum))); 1350 1112 *status = NT_STATUS_BAD_NETWORK_NAME; 1351 1113 return NULL; … … 1354 1116 DEBUG(5, ("making a connection to 'normal' service %s\n", service)); 1355 1117 1356 return make_connection_smb1(sconn, snum, vuser, 1357 password, 1118 return make_connection_smb1(req, now, snum, vuser, 1358 1119 dev, status); 1359 1120 } … … 1363 1124 ****************************************************************************/ 1364 1125 1365 void close_cnum(connection_struct *conn, uint 16vuid)1126 void close_cnum(connection_struct *conn, uint64_t vuid) 1366 1127 { 1367 1128 file_close_conn(conn); … … 1373 1134 change_to_root_user(); 1374 1135 1375 DEBUG(IS_IPC(conn)?3: 1, ("%s (%s) closed connection to service %s\n",1136 DEBUG(IS_IPC(conn)?3:2, ("%s (%s) closed connection to service %s\n", 1376 1137 get_remote_machine_name(), 1377 conn->sconn->client_id.addr, 1378 lp_servicename(SNUM(conn)))); 1379 1380 /* Call VFS disconnect hook */ 1381 SMB_VFS_DISCONNECT(conn); 1382 1383 yield_connection(conn, lp_servicename(SNUM(conn))); 1138 tsocket_address_string(conn->sconn->remote_address, 1139 talloc_tos()), 1140 lp_servicename(talloc_tos(), SNUM(conn)))); 1384 1141 1385 1142 /* make sure we leave the directory available for unmount */ 1386 1143 vfs_ChDir(conn, "/"); 1387 1144 1145 /* Call VFS disconnect hook */ 1146 SMB_VFS_DISCONNECT(conn); 1147 1388 1148 /* execute any "postexec = " line */ 1389 if (*lp_postexec( SNUM(conn)) &&1149 if (*lp_postexec(talloc_tos(), SNUM(conn)) && 1390 1150 change_to_user(conn, vuid)) { 1391 1151 char *cmd = talloc_sub_advanced(talloc_tos(), 1392 lp_servicename( SNUM(conn)),1393 conn->session_info->unix_ name,1152 lp_servicename(talloc_tos(), SNUM(conn)), 1153 conn->session_info->unix_info->unix_name, 1394 1154 conn->connectpath, 1395 conn->session_info->u tok.gid,1396 conn->session_info-> sanitized_username,1397 conn->session_info->info 3->base.domain.string,1398 lp_postexec( SNUM(conn)));1155 conn->session_info->unix_token->gid, 1156 conn->session_info->unix_info->sanitized_username, 1157 conn->session_info->info->domain_name, 1158 lp_postexec(talloc_tos(), SNUM(conn))); 1399 1159 smbrun(cmd,NULL); 1400 1160 TALLOC_FREE(cmd); … … 1404 1164 change_to_root_user(); 1405 1165 /* execute any "root postexec = " line */ 1406 if (*lp_root postexec(SNUM(conn))) {1166 if (*lp_root_postexec(talloc_tos(), SNUM(conn))) { 1407 1167 char *cmd = talloc_sub_advanced(talloc_tos(), 1408 lp_servicename( SNUM(conn)),1409 conn->session_info->unix_ name,1168 lp_servicename(talloc_tos(), SNUM(conn)), 1169 conn->session_info->unix_info->unix_name, 1410 1170 conn->connectpath, 1411 conn->session_info->u tok.gid,1412 conn->session_info-> sanitized_username,1413 conn->session_info->info 3->base.domain.string,1414 lp_root postexec(SNUM(conn)));1171 conn->session_info->unix_token->gid, 1172 conn->session_info->unix_info->sanitized_username, 1173 conn->session_info->info->domain_name, 1174 lp_root_postexec(talloc_tos(), SNUM(conn))); 1415 1175 smbrun(cmd,NULL); 1416 1176 TALLOC_FREE(cmd);
Note:
See TracChangeset
for help on using the changeset viewer.