00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "includes.h"
00022
00023 extern userdom_struct current_user_info;
00024
00025 static BOOL canonicalize_path(connection_struct *conn, pstring path)
00026 {
00027 #ifdef REALPATH_TAKES_NULL
00028 char *resolved_name = SMB_VFS_REALPATH(conn,path,NULL);
00029 if (!resolved_name) {
00030 return False;
00031 }
00032 pstrcpy(path, resolved_name);
00033 SAFE_FREE(resolved_name);
00034 return True;
00035 #else
00036 #ifdef PATH_MAX
00037 char resolved_name_buf[PATH_MAX+1];
00038 #else
00039 pstring resolved_name_buf;
00040 #endif
00041 char *resolved_name = SMB_VFS_REALPATH(conn,path,resolved_name_buf);
00042 if (!resolved_name) {
00043 return False;
00044 }
00045 pstrcpy(path, resolved_name);
00046 return True;
00047 #endif
00048 }
00049
00050
00051
00052
00053
00054
00055
00056 void set_conn_connectpath(connection_struct *conn, const pstring connectpath)
00057 {
00058 pstring destname;
00059 char *d = destname;
00060 const char *s = connectpath;
00061 BOOL start_of_name_component = True;
00062
00063 *d++ = '/';
00064
00065 while (*s) {
00066 if (*s == '/') {
00067
00068 while (*s == '/') {
00069 s++;
00070 }
00071 if ((d > destname + 1) && (*s != '\0')) {
00072 *d++ = '/';
00073 }
00074 start_of_name_component = True;
00075 continue;
00076 }
00077
00078 if (start_of_name_component) {
00079 if ((s[0] == '.') && (s[1] == '.') && (s[2] == '/' || s[2] == '\0')) {
00080
00081
00082
00083 if (s[2] == '/') {
00084 s += 3;
00085 } else {
00086 s += 2;
00087 }
00088
00089
00090 if ((d > destname) && (*(d-1) == '/')) {
00091 *(d-1) = '\0';
00092 d--;
00093 }
00094
00095
00096 if (d <= destname) {
00097 *d++ = '/';
00098 continue;
00099 }
00100
00101
00102 for (d--; d > destname; d--) {
00103 if (*d == '/') {
00104 break;
00105 }
00106 }
00107
00108 continue;
00109 } else if ((s[0] == '.') && ((s[1] == '\0') || s[1] == '/')) {
00110
00111 if (s[1] == '/') {
00112 s += 2;
00113 } else {
00114 s++;
00115 }
00116 continue;
00117 }
00118 }
00119
00120 if (!(*s & 0x80)) {
00121 *d++ = *s++;
00122 } else {
00123 size_t siz;
00124
00125 next_codepoint(s,&siz);
00126 switch(siz) {
00127 case 5:
00128 *d++ = *s++;
00129
00130 case 4:
00131 *d++ = *s++;
00132
00133 case 3:
00134 *d++ = *s++;
00135
00136 case 2:
00137 *d++ = *s++;
00138
00139 case 1:
00140 *d++ = *s++;
00141 break;
00142 default:
00143 break;
00144 }
00145 }
00146 start_of_name_component = False;
00147 }
00148 *d = '\0';
00149
00150
00151 if (d > destname + 1 && (*(d-1) == '/')) {
00152 *(d-1) = '\0';
00153 }
00154
00155 DEBUG(10,("set_conn_connectpath: service %s, connectpath = %s\n",
00156 lp_servicename(SNUM(conn)), destname ));
00157
00158 string_set(&conn->connectpath, destname);
00159 }
00160
00161
00162
00163
00164
00165 BOOL set_current_service(connection_struct *conn, uint16 flags, BOOL do_chdir)
00166 {
00167 static connection_struct *last_conn;
00168 static uint16 last_flags;
00169 int snum;
00170
00171 if (!conn) {
00172 last_conn = NULL;
00173 return(False);
00174 }
00175
00176 conn->lastused_count++;
00177
00178 snum = SNUM(conn);
00179
00180 if (do_chdir &&
00181 vfs_ChDir(conn,conn->connectpath) != 0 &&
00182 vfs_ChDir(conn,conn->origpath) != 0) {
00183 DEBUG(0,("chdir (%s) failed\n",
00184 conn->connectpath));
00185 return(False);
00186 }
00187
00188 if ((conn == last_conn) && (last_flags == flags)) {
00189 return(True);
00190 }
00191
00192 last_conn = conn;
00193 last_flags = flags;
00194
00195
00196 switch (lp_casesensitive(snum)) {
00197 case Auto:
00198 {
00199
00200 enum remote_arch_types ra_type = get_remote_arch();
00201 if ((ra_type != RA_SAMBA) && (ra_type != RA_CIFSFS)) {
00202
00203 conn->case_sensitive = False;
00204 } else {
00205 conn->case_sensitive = !(flags & FLAG_CASELESS_PATHNAMES);
00206 }
00207 }
00208 break;
00209 case True:
00210 conn->case_sensitive = True;
00211 break;
00212 default:
00213 conn->case_sensitive = False;
00214 break;
00215 }
00216 return(True);
00217 }
00218
00219
00220
00221
00222
00223 int add_home_service(const char *service, const char *username, const char *homedir)
00224 {
00225 int iHomeService;
00226
00227 if (!service || !homedir)
00228 return -1;
00229
00230 if ((iHomeService = lp_servicenumber(HOMES_NAME)) < 0)
00231 return -1;
00232
00233
00234
00235
00236
00237
00238
00239
00240 {
00241 const char *p = strchr(service,*lp_winbind_separator());
00242
00243
00244 if (p) {
00245 service = p + 1;
00246 }
00247 }
00248
00249 if (!lp_add_home(service, iHomeService, username, homedir)) {
00250 return -1;
00251 }
00252
00253 return lp_servicenumber(service);
00254
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264 int find_service(fstring service)
00265 {
00266 int iService;
00267
00268 all_string_sub(service,"\\","/",0);
00269
00270 iService = lp_servicenumber(service);
00271
00272
00273 if (iService < 0) {
00274 char *phome_dir = get_user_home_dir(service);
00275
00276 if(!phome_dir) {
00277
00278
00279
00280
00281 if(map_username(service))
00282 phome_dir = get_user_home_dir(service);
00283 }
00284
00285 DEBUG(3,("checking for home directory %s gave %s\n",service,
00286 phome_dir?phome_dir:"(NULL)"));
00287
00288 iService = add_home_service(service,service , phome_dir);
00289 }
00290
00291
00292 if (iService < 0) {
00293 int iPrinterService;
00294
00295 if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0) {
00296 DEBUG(3,("checking whether %s is a valid printer name...\n", service));
00297 if (pcap_printername_ok(service)) {
00298 DEBUG(3,("%s is a valid printer name\n", service));
00299 DEBUG(3,("adding %s as a printer service\n", service));
00300 lp_add_printer(service, iPrinterService);
00301 iService = lp_servicenumber(service);
00302 if (iService < 0) {
00303 DEBUG(0,("failed to add %s as a printer service!\n", service));
00304 }
00305 } else {
00306 DEBUG(3,("%s is not a valid printer name\n", service));
00307 }
00308 }
00309 }
00310
00311
00312 if (iService < 0) {
00313 }
00314
00315
00316 if (iService < 0 && *lp_usershare_path()) {
00317
00318 strlower_m(service);
00319 iService = load_usershare_service(service);
00320 }
00321
00322
00323 if (iService < 0) {
00324 char *pdefservice = lp_defaultservice();
00325 if (pdefservice && *pdefservice && !strequal(pdefservice,service) && !strstr_m(service,"..")) {
00326
00327
00328
00329
00330
00331
00332 pstring defservice;
00333 pstrcpy(defservice, pdefservice);
00334
00335
00336 if (strequal(defservice,HOMES_NAME) ||
00337 strequal(defservice, PRINTERS_NAME) ||
00338 strequal(defservice, "IPC$")) {
00339 goto fail;
00340 }
00341
00342 iService = find_service(defservice);
00343 if (iService >= 0) {
00344 all_string_sub(service, "_","/",0);
00345 iService = lp_add_service(service, iService);
00346 }
00347 }
00348 }
00349
00350 if (iService >= 0) {
00351 if (!VALID_SNUM(iService)) {
00352 DEBUG(0,("Invalid snum %d for %s\n",iService, service));
00353 iService = -1;
00354 }
00355 }
00356
00357 fail:
00358
00359 if (iService < 0)
00360 DEBUG(3,("find_service() failed to find service %s\n", service));
00361
00362 return (iService);
00363 }
00364
00365
00366
00367
00368
00369
00370
00371 static NTSTATUS share_sanity_checks(int snum, fstring dev)
00372 {
00373
00374 if (!lp_snum_ok(snum) ||
00375 !check_access(smbd_server_fd(),
00376 lp_hostsallow(snum), lp_hostsdeny(snum))) {
00377 return NT_STATUS_ACCESS_DENIED;
00378 }
00379
00380 if (dev[0] == '?' || !dev[0]) {
00381 if (lp_print_ok(snum)) {
00382 fstrcpy(dev,"LPT1:");
00383 } else if (strequal(lp_fstype(snum), "IPC")) {
00384 fstrcpy(dev, "IPC");
00385 } else {
00386 fstrcpy(dev,"A:");
00387 }
00388 }
00389
00390 strupper_m(dev);
00391
00392 if (lp_print_ok(snum)) {
00393 if (!strequal(dev, "LPT1:")) {
00394 return NT_STATUS_BAD_DEVICE_TYPE;
00395 }
00396 } else if (strequal(lp_fstype(snum), "IPC")) {
00397 if (!strequal(dev, "IPC")) {
00398 return NT_STATUS_BAD_DEVICE_TYPE;
00399 }
00400 } else if (!strequal(dev, "A:")) {
00401 return NT_STATUS_BAD_DEVICE_TYPE;
00402 }
00403
00404
00405 if (lp_print_ok(snum) && (strcmp(dev, "A:") == 0)) {
00406 fstrcpy(dev, "LPT1:");
00407 }
00408
00409 return NT_STATUS_OK;
00410 }
00411
00412 static NTSTATUS find_forced_user(connection_struct *conn, BOOL vuser_is_guest, fstring username)
00413 {
00414 int snum = conn->params->service;
00415 char *fuser, *found_username;
00416 NTSTATUS result;
00417
00418 if (!(fuser = talloc_string_sub(conn->mem_ctx, lp_force_user(snum), "%S",
00419 lp_servicename(snum)))) {
00420 return NT_STATUS_NO_MEMORY;
00421 }
00422
00423 result = create_token_from_username(conn->mem_ctx, fuser, vuser_is_guest,
00424 &conn->uid, &conn->gid, &found_username,
00425 &conn->nt_user_token);
00426 if (!NT_STATUS_IS_OK(result)) {
00427 return result;
00428 }
00429
00430 fstrcpy(username, found_username);
00431
00432 TALLOC_FREE(fuser);
00433 TALLOC_FREE(found_username);
00434 return NT_STATUS_OK;
00435 }
00436
00437
00438
00439
00440
00441
00442
00443
00444 static NTSTATUS find_forced_group(BOOL force_user,
00445 int snum, const char *username,
00446 DOM_SID *pgroup_sid,
00447 gid_t *pgid)
00448 {
00449 NTSTATUS result = NT_STATUS_NO_SUCH_GROUP;
00450 TALLOC_CTX *mem_ctx;
00451 DOM_SID group_sid;
00452 enum lsa_SidType type;
00453 char *groupname;
00454 BOOL user_must_be_member = False;
00455 gid_t gid;
00456
00457 ZERO_STRUCTP(pgroup_sid);
00458 *pgid = (gid_t)-1;
00459
00460 mem_ctx = talloc_new(NULL);
00461 if (mem_ctx == NULL) {
00462 DEBUG(0, ("talloc_new failed\n"));
00463 return NT_STATUS_NO_MEMORY;
00464 }
00465
00466 groupname = talloc_strdup(mem_ctx, lp_force_group(snum));
00467 if (groupname == NULL) {
00468 DEBUG(1, ("talloc_strdup failed\n"));
00469 result = NT_STATUS_NO_MEMORY;
00470 goto done;
00471 }
00472
00473 if (groupname[0] == '+') {
00474 user_must_be_member = True;
00475 groupname += 1;
00476 }
00477
00478 groupname = talloc_string_sub(mem_ctx, groupname,
00479 "%S", lp_servicename(snum));
00480
00481 if (!lookup_name_smbconf(mem_ctx, groupname,
00482 LOOKUP_NAME_ALL|LOOKUP_NAME_GROUP,
00483 NULL, NULL, &group_sid, &type)) {
00484 DEBUG(10, ("lookup_name_smbconf(%s) failed\n",
00485 groupname));
00486 goto done;
00487 }
00488
00489 if ((type != SID_NAME_DOM_GRP) && (type != SID_NAME_ALIAS) &&
00490 (type != SID_NAME_WKN_GRP)) {
00491 DEBUG(10, ("%s is a %s, not a group\n", groupname,
00492 sid_type_lookup(type)));
00493 goto done;
00494 }
00495
00496 if (!sid_to_gid(&group_sid, &gid)) {
00497 DEBUG(10, ("sid_to_gid(%s) for %s failed\n",
00498 sid_string_static(&group_sid), groupname));
00499 goto done;
00500 }
00501
00502
00503
00504
00505
00506
00507
00508
00509 if (force_user && user_must_be_member) {
00510 if (user_in_group_sid(username, &group_sid)) {
00511 sid_copy(pgroup_sid, &group_sid);
00512 *pgid = gid;
00513 DEBUG(3,("Forced group %s for member %s\n",
00514 groupname, username));
00515 } else {
00516 DEBUG(0,("find_forced_group: forced user %s is not a member "
00517 "of forced group %s. Disallowing access.\n",
00518 username, groupname ));
00519 result = NT_STATUS_MEMBER_NOT_IN_GROUP;
00520 goto done;
00521 }
00522 } else {
00523 sid_copy(pgroup_sid, &group_sid);
00524 *pgid = gid;
00525 DEBUG(3,("Forced group %s\n", groupname));
00526 }
00527
00528 result = NT_STATUS_OK;
00529 done:
00530 TALLOC_FREE(mem_ctx);
00531 return result;
00532 }
00533
00534
00535
00536
00537
00538
00539 static connection_struct *make_connection_snum(int snum, user_struct *vuser,
00540 DATA_BLOB password,
00541 const char *pdev,
00542 NTSTATUS *status)
00543 {
00544 struct passwd *pass = NULL;
00545 BOOL guest = False;
00546 connection_struct *conn;
00547 SMB_STRUCT_STAT st;
00548 fstring user;
00549 fstring dev;
00550 int ret;
00551
00552 *user = 0;
00553 fstrcpy(dev, pdev);
00554 SET_STAT_INVALID(st);
00555
00556 if (NT_STATUS_IS_ERR(*status = share_sanity_checks(snum, dev))) {
00557 return NULL;
00558 }
00559
00560 conn = conn_new();
00561 if (!conn) {
00562 DEBUG(0,("Couldn't find free connection.\n"));
00563 *status = NT_STATUS_INSUFFICIENT_RESOURCES;
00564 return NULL;
00565 }
00566
00567 conn->params->service = snum;
00568 conn->nt_user_token = NULL;
00569
00570 if (lp_guest_only(snum)) {
00571 const char *guestname = lp_guestaccount();
00572 NTSTATUS status2;
00573 char *found_username = NULL;
00574
00575 guest = True;
00576 pass = getpwnam_alloc(NULL, guestname);
00577 if (!pass) {
00578 DEBUG(0,("make_connection_snum: Invalid guest "
00579 "account %s??\n",guestname));
00580 conn_free(conn);
00581 *status = NT_STATUS_NO_SUCH_USER;
00582 return NULL;
00583 }
00584 status2 = create_token_from_username(conn->mem_ctx, pass->pw_name, True,
00585 &conn->uid, &conn->gid,
00586 &found_username,
00587 &conn->nt_user_token);
00588 if (!NT_STATUS_IS_OK(status2)) {
00589 TALLOC_FREE(pass);
00590 conn_free(conn);
00591 *status = status2;
00592 return NULL;
00593 }
00594 fstrcpy(user, found_username);
00595 string_set(&conn->user,user);
00596 conn->force_user = True;
00597 TALLOC_FREE(found_username);
00598 TALLOC_FREE(pass);
00599 DEBUG(3,("Guest only user %s\n",user));
00600 } else if (vuser) {
00601 if (vuser->guest) {
00602 if (!lp_guest_ok(snum)) {
00603 DEBUG(2, ("guest user (from session setup) "
00604 "not permitted to access this share "
00605 "(%s)\n", lp_servicename(snum)));
00606 conn_free(conn);
00607 *status = NT_STATUS_ACCESS_DENIED;
00608 return NULL;
00609 }
00610 } else {
00611 if (!user_ok_token(vuser->user.unix_name,
00612 vuser->nt_user_token, snum)) {
00613 DEBUG(2, ("user '%s' (from session setup) not "
00614 "permitted to access this share "
00615 "(%s)\n", vuser->user.unix_name,
00616 lp_servicename(snum)));
00617 conn_free(conn);
00618 *status = NT_STATUS_ACCESS_DENIED;
00619 return NULL;
00620 }
00621 }
00622 conn->vuid = vuser->vuid;
00623 conn->uid = vuser->uid;
00624 conn->gid = vuser->gid;
00625 string_set(&conn->user,vuser->user.unix_name);
00626 fstrcpy(user,vuser->user.unix_name);
00627 guest = vuser->guest;
00628 } else if (lp_security() == SEC_SHARE) {
00629 NTSTATUS status2;
00630 char *found_username = NULL;
00631
00632
00633
00634 add_session_user(lp_servicename(snum));
00635
00636 if (!authorise_login(snum,user,password,&guest)) {
00637 DEBUG( 2, ( "Invalid username/password for [%s]\n",
00638 lp_servicename(snum)) );
00639 conn_free(conn);
00640 *status = NT_STATUS_WRONG_PASSWORD;
00641 return NULL;
00642 }
00643 pass = Get_Pwnam(user);
00644 status2 = create_token_from_username(conn->mem_ctx, pass->pw_name, True,
00645 &conn->uid, &conn->gid,
00646 &found_username,
00647 &conn->nt_user_token);
00648 if (!NT_STATUS_IS_OK(status2)) {
00649 conn_free(conn);
00650 *status = status2;
00651 return NULL;
00652 }
00653 fstrcpy(user, found_username);
00654 string_set(&conn->user,user);
00655 TALLOC_FREE(found_username);
00656 conn->force_user = True;
00657 } else {
00658 DEBUG(0, ("invalid VUID (vuser) but not in security=share\n"));
00659 conn_free(conn);
00660 *status = NT_STATUS_ACCESS_DENIED;
00661 return NULL;
00662 }
00663
00664 add_session_user(user);
00665
00666 safe_strcpy(conn->client_address, client_addr(),
00667 sizeof(conn->client_address)-1);
00668 conn->num_files_open = 0;
00669 conn->lastused = conn->lastused_count = time(NULL);
00670 conn->used = True;
00671 conn->printer = (strncmp(dev,"LPT",3) == 0);
00672 conn->ipc = ( (strncmp(dev,"IPC",3) == 0) ||
00673 ( lp_enable_asu_support() && strequal(dev,"ADMIN$")) );
00674 conn->dirptr = NULL;
00675
00676
00677 if (lp_casesensitive(snum) == Auto) {
00678
00679
00680 conn->case_sensitive = False;
00681 } else {
00682 conn->case_sensitive = (BOOL)lp_casesensitive(snum);
00683 }
00684
00685 conn->case_preserve = lp_preservecase(snum);
00686 conn->short_case_preserve = lp_shortpreservecase(snum);
00687
00688 conn->veto_list = NULL;
00689 conn->hide_list = NULL;
00690 conn->veto_oplock_list = NULL;
00691 conn->aio_write_behind_list = NULL;
00692 string_set(&conn->dirpath,"");
00693 string_set(&conn->user,user);
00694
00695 conn->read_only = lp_readonly(SNUM(conn));
00696 conn->admin_user = False;
00697
00698
00699
00700
00701
00702
00703
00704 if (*lp_force_user(snum)) {
00705 NTSTATUS status2;
00706
00707 status2 = find_forced_user(conn,
00708 (vuser != NULL) && vuser->guest,
00709 user);
00710 if (!NT_STATUS_IS_OK(status2)) {
00711 conn_free(conn);
00712 *status = status2;
00713 return NULL;
00714 }
00715 string_set(&conn->user,user);
00716 conn->force_user = True;
00717 DEBUG(3,("Forced user %s\n",user));
00718 }
00719
00720
00721
00722
00723
00724
00725 if (*lp_force_group(snum)) {
00726 NTSTATUS status2;
00727 DOM_SID group_sid;
00728
00729 status2 = find_forced_group(conn->force_user,
00730 snum, user,
00731 &group_sid, &conn->gid);
00732 if (!NT_STATUS_IS_OK(status2)) {
00733 conn_free(conn);
00734 *status = status2;
00735 return NULL;
00736 }
00737
00738 if ((conn->nt_user_token == NULL) && (vuser != NULL)) {
00739
00740
00741
00742
00743 conn->nt_user_token = dup_nt_token(
00744 NULL, vuser->nt_user_token);
00745 if (conn->nt_user_token == NULL) {
00746 DEBUG(0, ("dup_nt_token failed\n"));
00747 conn_free(conn);
00748 *status = NT_STATUS_NO_MEMORY;
00749 return NULL;
00750 }
00751 }
00752
00753
00754
00755
00756
00757 if (conn->nt_user_token != NULL) {
00758
00759 sid_copy(&conn->nt_user_token->user_sids[1],
00760 &group_sid);
00761
00762 }
00763 conn->force_group = True;
00764 }
00765
00766 if (conn->nt_user_token != NULL) {
00767 size_t i;
00768
00769
00770
00771
00772
00773 conn->ngroups = 0;
00774 conn->groups = NULL;
00775
00776 for (i=0; i<conn->nt_user_token->num_sids; i++) {
00777 gid_t gid;
00778 DOM_SID *sid = &conn->nt_user_token->user_sids[i];
00779
00780 if (!sid_to_gid(sid, &gid)) {
00781 DEBUG(10, ("Could not convert SID %s to gid, "
00782 "ignoring it\n",
00783 sid_string_static(sid)));
00784 continue;
00785 }
00786 if (!add_gid_to_array_unique(conn->mem_ctx, gid, &conn->groups,
00787 &conn->ngroups)) {
00788 DEBUG(0, ("add_gid_to_array_unique failed\n"));
00789 conn_free(conn);
00790 *status = NT_STATUS_NO_MEMORY;
00791 return NULL;
00792 }
00793 }
00794 }
00795
00796 {
00797 pstring s;
00798 pstrcpy(s,lp_pathname(snum));
00799 standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
00800 conn->connectpath, conn->gid,
00801 get_current_username(),
00802 current_user_info.domain,
00803 s, sizeof(s));
00804 set_conn_connectpath(conn,s);
00805 DEBUG(3,("Connect path is '%s' for service [%s]\n",s,
00806 lp_servicename(snum)));
00807 }
00808
00809
00810
00811
00812
00813
00814
00815
00816 {
00817 BOOL can_write = False;
00818 NT_USER_TOKEN *token = conn->nt_user_token ?
00819 conn->nt_user_token :
00820 (vuser ? vuser->nt_user_token : NULL);
00821
00822
00823
00824
00825
00826
00827
00828 if (token == NULL) {
00829 DEBUG(0,("make_connection: connection to %s "
00830 "denied due to missing "
00831 "NT token.\n",
00832 lp_servicename(snum)));
00833 conn_free(conn);
00834 *status = NT_STATUS_ACCESS_DENIED;
00835 return NULL;
00836 }
00837
00838 can_write = share_access_check(token,
00839 lp_servicename(snum),
00840 FILE_WRITE_DATA);
00841
00842 if (!can_write) {
00843 if (!share_access_check(token,
00844 lp_servicename(snum),
00845 FILE_READ_DATA)) {
00846
00847 DEBUG(0,("make_connection: connection to %s "
00848 "denied due to security "
00849 "descriptor.\n",
00850 lp_servicename(snum)));
00851 conn_free(conn);
00852 *status = NT_STATUS_ACCESS_DENIED;
00853 return NULL;
00854 } else {
00855 conn->read_only = True;
00856 }
00857 }
00858 }
00859
00860
00861 if (!smbd_vfs_init(conn)) {
00862 DEBUG(0, ("vfs_init failed for service %s\n",
00863 lp_servicename(snum)));
00864 conn_free(conn);
00865 *status = NT_STATUS_BAD_NETWORK_NAME;
00866 return NULL;
00867 }
00868
00869
00870
00871
00872
00873
00874
00875
00876 if (!lp_widelinks(snum)) {
00877 pstring s;
00878 pstrcpy(s,conn->connectpath);
00879 canonicalize_path(conn, s);
00880 set_conn_connectpath(conn,s);
00881 }
00882
00883 if ((!conn->printer) && (!conn->ipc)) {
00884 conn->notify_ctx = notify_init(conn->mem_ctx, server_id_self(),
00885 smbd_messaging_context(),
00886 smbd_event_context(),
00887 conn);
00888 }
00889
00890
00891
00892 if (!claim_connection(conn,
00893 lp_servicename(snum),
00894 lp_max_connections(snum),
00895 False,0)) {
00896 DEBUG(1,("too many connections - rejected\n"));
00897 conn_free(conn);
00898 *status = NT_STATUS_INSUFFICIENT_RESOURCES;
00899 return NULL;
00900 }
00901
00902
00903
00904
00905 if (*lp_rootpreexec(snum)) {
00906 pstring cmd;
00907 pstrcpy(cmd,lp_rootpreexec(snum));
00908 standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
00909 conn->connectpath, conn->gid,
00910 get_current_username(),
00911 current_user_info.domain,
00912 cmd, sizeof(cmd));
00913 DEBUG(5,("cmd=%s\n",cmd));
00914 ret = smbrun(cmd,NULL);
00915 if (ret != 0 && lp_rootpreexec_close(snum)) {
00916 DEBUG(1,("root preexec gave %d - failing "
00917 "connection\n", ret));
00918 yield_connection(conn, lp_servicename(snum));
00919 conn_free(conn);
00920 *status = NT_STATUS_ACCESS_DENIED;
00921 return NULL;
00922 }
00923 }
00924
00925
00926 if (!change_to_user(conn, conn->vuid)) {
00927
00928 DEBUG(0,("Can't become connected user!\n"));
00929 yield_connection(conn, lp_servicename(snum));
00930 conn_free(conn);
00931 *status = NT_STATUS_LOGON_FAILURE;
00932 return NULL;
00933 }
00934
00935
00936
00937
00938
00939
00940
00941
00942 if (*lp_preexec(snum)) {
00943 pstring cmd;
00944 pstrcpy(cmd,lp_preexec(snum));
00945 standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
00946 conn->connectpath, conn->gid,
00947 get_current_username(),
00948 current_user_info.domain,
00949 cmd, sizeof(cmd));
00950 ret = smbrun(cmd,NULL);
00951 if (ret != 0 && lp_preexec_close(snum)) {
00952 DEBUG(1,("preexec gave %d - failing connection\n",
00953 ret));
00954 change_to_root_user();
00955 yield_connection(conn, lp_servicename(snum));
00956 conn_free(conn);
00957 *status = NT_STATUS_ACCESS_DENIED;
00958 return NULL;
00959 }
00960 }
00961
00962 #ifdef WITH_FAKE_KASERVER
00963 if (lp_afs_share(snum)) {
00964 afs_login(conn);
00965 }
00966 #endif
00967
00968
00969 if (!IS_IPC(conn) && !IS_PRINT(conn)) {
00970 set_namearray( &conn->veto_list, lp_veto_files(snum));
00971 set_namearray( &conn->hide_list, lp_hide_files(snum));
00972 set_namearray( &conn->veto_oplock_list, lp_veto_oplocks(snum));
00973 }
00974
00975
00976
00977
00978
00979 if (SMB_VFS_CONNECT(conn, lp_servicename(snum), user) < 0) {
00980 DEBUG(0,("make_connection: VFS make connection failed!\n"));
00981 change_to_root_user();
00982 yield_connection(conn, lp_servicename(snum));
00983 conn_free(conn);
00984 *status = NT_STATUS_UNSUCCESSFUL;
00985 return NULL;
00986 }
00987
00988
00989
00990
00991
00992
00993 if ((ret = SMB_VFS_STAT(conn, conn->connectpath, &st)) != 0 ||
00994 !S_ISDIR(st.st_mode)) {
00995 if (ret == 0 && !S_ISDIR(st.st_mode)) {
00996 DEBUG(0,("'%s' is not a directory, when connecting to "
00997 "[%s]\n", conn->connectpath,
00998 lp_servicename(snum)));
00999 } else {
01000 DEBUG(0,("'%s' does not exist or permission denied "
01001 "when connecting to [%s] Error was %s\n",
01002 conn->connectpath, lp_servicename(snum),
01003 strerror(errno) ));
01004 }
01005 change_to_root_user();
01006
01007 SMB_VFS_DISCONNECT(conn);
01008 yield_connection(conn, lp_servicename(snum));
01009 conn_free(conn);
01010 *status = NT_STATUS_BAD_NETWORK_NAME;
01011 return NULL;
01012 }
01013
01014 string_set(&conn->origpath,conn->connectpath);
01015
01016 #if SOFTLINK_OPTIMISATION
01017
01018 if (vfs_ChDir(conn,conn->connectpath) == 0) {
01019 pstring s;
01020 pstrcpy(s,conn->connectpath);
01021 vfs_GetWd(conn,s);
01022 set_conn_connectpath(conn,s);
01023 vfs_ChDir(conn,conn->connectpath);
01024 }
01025 #endif
01026
01027
01028
01029
01030
01031
01032
01033 if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) {
01034 dbgtext( "%s (%s) ", get_remote_machine_name(),
01035 conn->client_address );
01036 dbgtext( "%s", srv_is_signing_active() ? "signed " : "");
01037 dbgtext( "connect to service %s ", lp_servicename(snum) );
01038 dbgtext( "initially as user %s ", user );
01039 dbgtext( "(uid=%d, gid=%d) ", (int)geteuid(), (int)getegid() );
01040 dbgtext( "(pid %d)\n", (int)sys_getpid() );
01041 }
01042
01043
01044 change_to_root_user();
01045 return(conn);
01046 }
01047
01048
01049
01050
01051
01052
01053 connection_struct *make_connection_with_chdir(const char *service_in,
01054 DATA_BLOB password,
01055 const char *dev, uint16 vuid,
01056 NTSTATUS *status)
01057 {
01058 connection_struct *conn = NULL;
01059
01060 conn = make_connection(service_in, password, dev, vuid, status);
01061
01062
01063
01064
01065
01066
01067 if ( conn && vfs_ChDir(conn,conn->connectpath) != 0 ) {
01068 DEBUG(0,("move_driver_to_download_area: Can't change "
01069 "directory to %s for [print$] (%s)\n",
01070 conn->connectpath,strerror(errno)));
01071 yield_connection(conn, lp_servicename(SNUM(conn)));
01072 conn_free(conn);
01073 *status = NT_STATUS_UNSUCCESSFUL;
01074 return NULL;
01075 }
01076
01077 return conn;
01078 }
01079
01080
01081
01082
01083
01084
01085
01086 connection_struct *make_connection(const char *service_in, DATA_BLOB password,
01087 const char *pdev, uint16 vuid,
01088 NTSTATUS *status)
01089 {
01090 uid_t euid;
01091 user_struct *vuser = NULL;
01092 fstring service;
01093 fstring dev;
01094 int snum = -1;
01095
01096 fstrcpy(dev, pdev);
01097
01098
01099
01100 if (!non_root_mode() && (euid = geteuid()) != 0) {
01101 DEBUG(0,("make_connection: PANIC ERROR. Called as nonroot "
01102 "(%u)\n", (unsigned int)euid ));
01103 smb_panic("make_connection: PANIC ERROR. Called as nonroot\n");
01104 }
01105
01106 if (conn_num_open() > 2047) {
01107 *status = NT_STATUS_INSUFF_SERVER_RESOURCES;
01108 return NULL;
01109 }
01110
01111 if(lp_security() != SEC_SHARE) {
01112 vuser = get_valid_user_struct(vuid);
01113 if (!vuser) {
01114 DEBUG(1,("make_connection: refusing to connect with "
01115 "no session setup\n"));
01116 *status = NT_STATUS_ACCESS_DENIED;
01117 return NULL;
01118 }
01119 }
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130 if (strequal(service_in,HOMES_NAME)) {
01131 if(lp_security() != SEC_SHARE) {
01132 DATA_BLOB no_pw = data_blob(NULL, 0);
01133 if (vuser->homes_snum == -1) {
01134 DEBUG(2, ("[homes] share not available for "
01135 "this user because it was not found "
01136 "or created at session setup "
01137 "time\n"));
01138 *status = NT_STATUS_BAD_NETWORK_NAME;
01139 return NULL;
01140 }
01141 DEBUG(5, ("making a connection to [homes] service "
01142 "created at session setup time\n"));
01143 return make_connection_snum(vuser->homes_snum,
01144 vuser, no_pw,
01145 dev, status);
01146 } else {
01147
01148
01149 if (*current_user_info.smb_name) {
01150 fstring unix_username;
01151 fstrcpy(unix_username,
01152 current_user_info.smb_name);
01153 map_username(unix_username);
01154 snum = find_service(unix_username);
01155 }
01156 if (snum != -1) {
01157 DEBUG(5, ("making a connection to 'homes' "
01158 "service %s based on "
01159 "security=share\n", service_in));
01160 return make_connection_snum(snum, NULL,
01161 password,
01162 dev, status);
01163 }
01164 }
01165 } else if ((lp_security() != SEC_SHARE) && (vuser->homes_snum != -1)
01166 && strequal(service_in,
01167 lp_servicename(vuser->homes_snum))) {
01168 DATA_BLOB no_pw = data_blob(NULL, 0);
01169 DEBUG(5, ("making a connection to 'homes' service [%s] "
01170 "created at session setup time\n", service_in));
01171 return make_connection_snum(vuser->homes_snum,
01172 vuser, no_pw,
01173 dev, status);
01174 }
01175
01176 fstrcpy(service, service_in);
01177
01178 strlower_m(service);
01179
01180 snum = find_service(service);
01181
01182 if (snum < 0) {
01183 if (strequal(service,"IPC$") ||
01184 (lp_enable_asu_support() && strequal(service,"ADMIN$"))) {
01185 DEBUG(3,("refusing IPC connection to %s\n", service));
01186 *status = NT_STATUS_ACCESS_DENIED;
01187 return NULL;
01188 }
01189
01190 DEBUG(0,("%s (%s) couldn't find service %s\n",
01191 get_remote_machine_name(), client_addr(), service));
01192 *status = NT_STATUS_BAD_NETWORK_NAME;
01193 return NULL;
01194 }
01195
01196
01197 if (lp_host_msdfs() && (*lp_msdfs_proxy(snum) != '\0')) {
01198 DEBUG(3, ("refusing connection to dfs proxy share '%s' "
01199 "(pointing to %s)\n",
01200 service, lp_msdfs_proxy(snum)));
01201 *status = NT_STATUS_BAD_NETWORK_NAME;
01202 return NULL;
01203 }
01204
01205 DEBUG(5, ("making a connection to 'normal' service %s\n", service));
01206
01207 return make_connection_snum(snum, vuser,
01208 password,
01209 dev, status);
01210 }
01211
01212
01213
01214
01215
01216 void close_cnum(connection_struct *conn, uint16 vuid)
01217 {
01218 if (IS_IPC(conn)) {
01219 pipe_close_conn(conn);
01220 } else {
01221 file_close_conn(conn);
01222 dptr_closecnum(conn);
01223 }
01224
01225 change_to_root_user();
01226
01227 DEBUG(IS_IPC(conn)?3:1, ("%s (%s) closed connection to service %s\n",
01228 get_remote_machine_name(),
01229 conn->client_address,
01230 lp_servicename(SNUM(conn))));
01231
01232
01233 SMB_VFS_DISCONNECT(conn);
01234
01235 yield_connection(conn, lp_servicename(SNUM(conn)));
01236
01237
01238 vfs_ChDir(conn, "/");
01239
01240
01241 if (*lp_postexec(SNUM(conn)) &&
01242 change_to_user(conn, vuid)) {
01243 pstring cmd;
01244 pstrcpy(cmd,lp_postexec(SNUM(conn)));
01245 standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
01246 conn->connectpath, conn->gid,
01247 get_current_username(),
01248 current_user_info.domain,
01249 cmd, sizeof(cmd));
01250 smbrun(cmd,NULL);
01251 change_to_root_user();
01252 }
01253
01254 change_to_root_user();
01255
01256 if (*lp_rootpostexec(SNUM(conn))) {
01257 pstring cmd;
01258 pstrcpy(cmd,lp_rootpostexec(SNUM(conn)));
01259 standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
01260 conn->connectpath, conn->gid,
01261 get_current_username(),
01262 current_user_info.domain,
01263 cmd, sizeof(cmd));
01264 smbrun(cmd,NULL);
01265 }
01266
01267 conn_free(conn);
01268 }