~ubuntu-branches/ubuntu/gutsy/samba/gutsy-updates

« back to all changes in this revision

Viewing changes to source/smbd/service.c

  • Committer: Bazaar Package Importer
  • Author(s): Andrew Mitchell
  • Date: 2006-11-28 20:14:37 UTC
  • mfrom: (0.10.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20061128201437-a6x4lzlhempazocp
Tags: 3.0.23d-1ubuntu1
* Merge from debian unstable.
* Drop python2.4-samba, replace with python-samba. Added Conflicts/Replaces
  on python2.4-samba
* Drop track-connection-dos.patch, ubuntu-winbind-panic.patch, 
  ubuntu-fix-ldap.patch, ubuntu-setlocale.patch, ubuntu-setlocale-fixes.patch
* Remaining Ubuntu changes:
  - Revert Debian's installation of mount.cifs and umount.cifs as suid
  - Comment out the default [homes] shares and add more verbose comments to
    explain what they do and how they work (closes: launchpad.net/27608)
  - Add a "valid users = %S" stanza to the commented-out [homes] section, to
    show users how to restrict access to \\server\username to only username.
  - Change the (commented-out) "printer admin" example to use "@lpadmin"
    instead of "@ntadmin", since the lpadmin group is used for spool admin.
  - Alter the panic-action script to encourage users to report their
    bugs in Ubuntu packages to Ubuntu, rather than reporting to Debian.
    Modify text to more closely match the Debian script
  - Munge our init script to deal with the fact that our implementation
    (or lack thereof) of log_daemon_msg and log_progress_msg differs
    from Debian's implementation of the same (Ubuntu #19691)
  - Kept ubuntu-auxsrc.patch: some auxilliary sources (undocumented in 
    previous changelogs)
  - Set default workgroup to MSHOME

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 
21
21
#include "includes.h"
22
22
 
23
 
extern struct timeval smb_last_time;
24
23
extern userdom_struct current_user_info;
25
24
 
26
25
/****************************************************************************
 
26
 Ensure when setting connectpath it is a canonicalized (no ./ // or ../)
 
27
 absolute path stating in / and not ending in /.
 
28
 Observent people will notice a similarity between this and check_path_syntax :-).
 
29
****************************************************************************/
 
30
 
 
31
void set_conn_connectpath(connection_struct *conn, const pstring connectpath)
 
32
{
 
33
        pstring destname;
 
34
        char *d = destname;
 
35
        const char *s = connectpath;
 
36
        BOOL start_of_name_component = True;
 
37
 
 
38
        *d++ = '/'; /* Always start with root. */
 
39
 
 
40
        while (*s) {
 
41
                if (*s == '/') {
 
42
                        /* Eat multiple '/' */
 
43
                        while (*s == '/') {
 
44
                                s++;
 
45
                        }
 
46
                        if ((d > destname + 1) && (*s != '\0')) {
 
47
                                *d++ = '/';
 
48
                        }
 
49
                        start_of_name_component = True;
 
50
                        continue;
 
51
                }
 
52
 
 
53
                if (start_of_name_component) {
 
54
                        if ((s[0] == '.') && (s[1] == '.') && (s[2] == '/' || s[2] == '\0')) {
 
55
                                /* Uh oh - "/../" or "/..\0" ! */
 
56
 
 
57
                                /* Go past the ../ or .. */
 
58
                                if (s[2] == '/') {
 
59
                                        s += 3;
 
60
                                } else {
 
61
                                        s += 2; /* Go past the .. */
 
62
                                }
 
63
 
 
64
                                /* If  we just added a '/' - delete it */
 
65
                                if ((d > destname) && (*(d-1) == '/')) {
 
66
                                        *(d-1) = '\0';
 
67
                                        d--;
 
68
                                }
 
69
 
 
70
                                /* Are we at the start ? Can't go back further if so. */
 
71
                                if (d <= destname) {
 
72
                                        *d++ = '/'; /* Can't delete root */
 
73
                                        continue;
 
74
                                }
 
75
                                /* Go back one level... */
 
76
                                /* Decrement d first as d points to the *next* char to write into. */
 
77
                                for (d--; d > destname; d--) {
 
78
                                        if (*d == '/') {
 
79
                                                break;
 
80
                                        }
 
81
                                }
 
82
                                /* We're still at the start of a name component, just the previous one. */
 
83
                                continue;
 
84
                        } else if ((s[0] == '.') && ((s[1] == '\0') || s[1] == '/')) {
 
85
                                /* Component of pathname can't be "." only - skip the '.' . */
 
86
                                if (s[1] == '/') {
 
87
                                        s += 2;
 
88
                                } else {
 
89
                                        s++;
 
90
                                }
 
91
                                continue;
 
92
                        }
 
93
                }
 
94
 
 
95
                if (!(*s & 0x80)) {
 
96
                        *d++ = *s++;
 
97
                } else {
 
98
                        switch(next_mb_char_size(s)) {
 
99
                                case 4:
 
100
                                        *d++ = *s++;
 
101
                                case 3:
 
102
                                        *d++ = *s++;
 
103
                                case 2:
 
104
                                        *d++ = *s++;
 
105
                                case 1:
 
106
                                        *d++ = *s++;
 
107
                                        break;
 
108
                                default:
 
109
                                        break;
 
110
                        }
 
111
                }
 
112
                start_of_name_component = False;
 
113
        }
 
114
        *d = '\0';
 
115
 
 
116
        /* And must not end in '/' */
 
117
        if (d > destname + 1 && (*(d-1) == '/')) {
 
118
                *(d-1) = '\0';
 
119
        }
 
120
 
 
121
        DEBUG(10,("set_conn_connectpath: service %s, connectpath = %s\n",
 
122
                lp_servicename(SNUM(conn)), destname ));
 
123
 
 
124
        string_set(&conn->connectpath, destname);
 
125
}
 
126
 
 
127
/****************************************************************************
27
128
 Load parameters specific to a connection/service.
28
129
****************************************************************************/
29
130
 
38
139
                return(False);
39
140
        }
40
141
 
41
 
        conn->lastused = smb_last_time.tv_sec;
 
142
        conn->lastused_count++;
42
143
 
43
144
        snum = SNUM(conn);
44
145
  
197
298
                }
198
299
        }
199
300
 
 
301
        /* Is it a usershare service ? */
 
302
        if (iService < 0 && *lp_usershare_path()) {
 
303
                /* Ensure the name is canonicalized. */
 
304
                strlower_m(service);
 
305
                iService = load_usershare_service(service);
 
306
        }
 
307
 
200
308
        if (iService >= 0) {
201
309
                if (!VALID_SNUM(iService)) {
202
310
                        DEBUG(0,("Invalid snum %d for %s\n",iService, service));
257
365
        return NT_STATUS_OK;
258
366
}
259
367
 
 
368
static NTSTATUS find_forced_user(int snum, BOOL vuser_is_guest,
 
369
                                 uid_t *uid, gid_t *gid, fstring username,
 
370
                                 struct nt_user_token **token)
 
371
{
 
372
        TALLOC_CTX *mem_ctx;
 
373
        char *fuser, *found_username;
 
374
        NTSTATUS result;
 
375
 
 
376
        mem_ctx = talloc_new(NULL);
 
377
        if (mem_ctx == NULL) {
 
378
                DEBUG(0, ("talloc_new failed\n"));
 
379
                return NT_STATUS_NO_MEMORY;
 
380
        }
 
381
 
 
382
        fuser = talloc_string_sub(mem_ctx, lp_force_user(snum), "%S",
 
383
                                  lp_servicename(snum));
 
384
        if (fuser == NULL) {
 
385
                result = NT_STATUS_NO_MEMORY;
 
386
                goto done;
 
387
        }
 
388
 
 
389
        result = create_token_from_username(mem_ctx, fuser, vuser_is_guest,
 
390
                                            uid, gid, &found_username,
 
391
                                            token);
 
392
        if (!NT_STATUS_IS_OK(result)) {
 
393
                goto done;
 
394
        }
 
395
 
 
396
        talloc_steal(NULL, *token);
 
397
        fstrcpy(username, found_username);
 
398
 
 
399
        result = NT_STATUS_OK;
 
400
 done:
 
401
        TALLOC_FREE(mem_ctx);
 
402
        return result;
 
403
}
 
404
 
 
405
/*
 
406
 * Go through lookup_name etc to find the force'd group.  
 
407
 *
 
408
 * Create a new token from src_token, replacing the primary group sid with the
 
409
 * one found.
 
410
 */
 
411
 
 
412
static NTSTATUS find_forced_group(BOOL force_user,
 
413
                                  int snum, const char *username,
 
414
                                  DOM_SID *pgroup_sid,
 
415
                                  gid_t *pgid)
 
416
{
 
417
        NTSTATUS result = NT_STATUS_NO_SUCH_GROUP;
 
418
        TALLOC_CTX *mem_ctx;
 
419
        DOM_SID group_sid;
 
420
        enum SID_NAME_USE type;
 
421
        char *groupname;
 
422
        BOOL user_must_be_member = False;
 
423
        gid_t gid;
 
424
 
 
425
        ZERO_STRUCTP(pgroup_sid);
 
426
        *pgid = (gid_t)-1;
 
427
 
 
428
        mem_ctx = talloc_new(NULL);
 
429
        if (mem_ctx == NULL) {
 
430
                DEBUG(0, ("talloc_new failed\n"));
 
431
                return NT_STATUS_NO_MEMORY;
 
432
        }
 
433
 
 
434
        groupname = talloc_strdup(mem_ctx, lp_force_group(snum));
 
435
        if (groupname == NULL) {
 
436
                DEBUG(1, ("talloc_strdup failed\n"));
 
437
                result = NT_STATUS_NO_MEMORY;
 
438
                goto done;
 
439
        }
 
440
 
 
441
        if (groupname[0] == '+') {
 
442
                user_must_be_member = True;
 
443
                groupname += 1;
 
444
        }
 
445
 
 
446
        groupname = talloc_string_sub(mem_ctx, groupname,
 
447
                                      "%S", lp_servicename(snum));
 
448
 
 
449
        if (!lookup_name_smbconf(mem_ctx, groupname,
 
450
                         LOOKUP_NAME_ALL|LOOKUP_NAME_GROUP,
 
451
                         NULL, NULL, &group_sid, &type)) {
 
452
                DEBUG(10, ("lookup_name_smbconf(%s) failed\n",
 
453
                           groupname));
 
454
                goto done;
 
455
        }
 
456
 
 
457
        if ((type != SID_NAME_DOM_GRP) && (type != SID_NAME_ALIAS) &&
 
458
            (type != SID_NAME_WKN_GRP)) {
 
459
                DEBUG(10, ("%s is a %s, not a group\n", groupname,
 
460
                           sid_type_lookup(type)));
 
461
                goto done;
 
462
        }
 
463
 
 
464
        if (!sid_to_gid(&group_sid, &gid)) {
 
465
                DEBUG(10, ("sid_to_gid(%s) for %s failed\n",
 
466
                           sid_string_static(&group_sid), groupname));
 
467
                goto done;
 
468
        }
 
469
 
 
470
        /*
 
471
         * If the user has been forced and the forced group starts with a '+',
 
472
         * then we only set the group to be the forced group if the forced
 
473
         * user is a member of that group.  Otherwise, the meaning of the '+'
 
474
         * would be ignored.
 
475
         */
 
476
 
 
477
        if (force_user && user_must_be_member) {
 
478
                if (user_in_group_sid(username, &group_sid)) {
 
479
                        sid_copy(pgroup_sid, &group_sid);
 
480
                        *pgid = gid;
 
481
                        DEBUG(3,("Forced group %s for member %s\n",
 
482
                                 groupname, username));
 
483
                } else {
 
484
                        DEBUG(0,("find_forced_group: forced user %s is not a member "
 
485
                                "of forced group %s. Disallowing access.\n",
 
486
                                username, groupname ));
 
487
                        result = NT_STATUS_MEMBER_NOT_IN_GROUP;
 
488
                        goto done;
 
489
                }
 
490
        } else {
 
491
                sid_copy(pgroup_sid, &group_sid);
 
492
                *pgid = gid;
 
493
                DEBUG(3,("Forced group %s\n", groupname));
 
494
        }
 
495
 
 
496
        result = NT_STATUS_OK;
 
497
 done:
 
498
        TALLOC_FREE(mem_ctx);
 
499
        return result;
 
500
}
 
501
 
260
502
/****************************************************************************
261
503
  Make a connection, given the snum to connect to, and the vuser of the
262
504
  connecting user if appropriate.
290
532
                return NULL;
291
533
        }
292
534
 
 
535
        conn->nt_user_token = NULL;
 
536
 
293
537
        if (lp_guest_only(snum)) {
294
538
                const char *guestname = lp_guestaccount();
 
539
                NTSTATUS status2;
 
540
                char *found_username;
295
541
                guest = True;
296
 
                pass = getpwnam_alloc(guestname);
 
542
                pass = getpwnam_alloc(NULL, guestname);
297
543
                if (!pass) {
298
544
                        DEBUG(0,("make_connection_snum: Invalid guest "
299
545
                                 "account %s??\n",guestname));
301
547
                        *status = NT_STATUS_NO_SUCH_USER;
302
548
                        return NULL;
303
549
                }
304
 
                fstrcpy(user,pass->pw_name);
 
550
                status2 = create_token_from_username(NULL, pass->pw_name, True,
 
551
                                                     &conn->uid, &conn->gid,
 
552
                                                     &found_username,
 
553
                                                     &conn->nt_user_token);
 
554
                if (!NT_STATUS_IS_OK(status2)) {
 
555
                        conn_free(conn);
 
556
                        *status = status2;
 
557
                        return NULL;
 
558
                }
 
559
                fstrcpy(user, found_username);
 
560
                string_set(&conn->user,user);
305
561
                conn->force_user = True;
306
 
                conn->uid = pass->pw_uid;
307
 
                conn->gid = pass->pw_gid;
308
 
                string_set(&conn->user,pass->pw_name);
309
 
                passwd_free(&pass);
 
562
                TALLOC_FREE(pass);
310
563
                DEBUG(3,("Guest only user %s\n",user));
311
564
        } else if (vuser) {
312
565
                if (vuser->guest) {
319
572
                                      return NULL;
320
573
                        }
321
574
                } else {
322
 
                        if (!user_ok(vuser->user.unix_name, snum,
323
 
                                     vuser->groups, vuser->n_groups)) {
 
575
                        if (!user_ok_token(vuser->user.unix_name,
 
576
                                           vuser->nt_user_token, snum)) {
324
577
                                DEBUG(2, ("user '%s' (from session setup) not "
325
578
                                          "permitted to access this share "
326
579
                                          "(%s)\n", vuser->user.unix_name,
337
590
                fstrcpy(user,vuser->user.unix_name);
338
591
                guest = vuser->guest; 
339
592
        } else if (lp_security() == SEC_SHARE) {
 
593
                NTSTATUS status2;
 
594
                char *found_username;
340
595
                /* add it as a possible user name if we 
341
596
                   are in share mode security */
342
597
                add_session_user(lp_servicename(snum));
349
604
                        return NULL;
350
605
                }
351
606
                pass = Get_Pwnam(user);
 
607
                status2 = create_token_from_username(NULL, pass->pw_name, True,
 
608
                                                     &conn->uid, &conn->gid,
 
609
                                                     &found_username,
 
610
                                                     &conn->nt_user_token);
 
611
                if (!NT_STATUS_IS_OK(status2)) {
 
612
                        conn_free(conn);
 
613
                        *status = status2;
 
614
                        return NULL;
 
615
                }
 
616
                fstrcpy(user, found_username);
 
617
                string_set(&conn->user,user);
352
618
                conn->force_user = True;
353
 
                conn->uid = pass->pw_uid;
354
 
                conn->gid = pass->pw_gid;
355
 
                string_set(&conn->user, pass->pw_name);
356
 
                fstrcpy(user, pass->pw_name);
357
 
 
358
619
        } else {
359
620
                DEBUG(0, ("invalid VUID (vuser) but not in security=share\n"));
360
621
                conn_free(conn);
367
628
        safe_strcpy(conn->client_address, client_addr(), 
368
629
                    sizeof(conn->client_address)-1);
369
630
        conn->num_files_open = 0;
370
 
        conn->lastused = time(NULL);
 
631
        conn->lastused = conn->lastused_count = time(NULL);
371
632
        conn->service = snum;
372
633
        conn->used = True;
373
634
        conn->printer = (strncmp(dev,"LPT",3) == 0);
393
654
        conn->aio_write_behind_list = NULL;
394
655
        string_set(&conn->dirpath,"");
395
656
        string_set(&conn->user,user);
396
 
        conn->nt_user_token = NULL;
397
657
 
398
658
        conn->read_only = lp_readonly(conn->service);
399
659
        conn->admin_user = False;
400
660
 
401
661
        /*
402
 
         * If force user is true, then store the
403
 
         * given userid and also the groups
404
 
         * of the user we're forcing.
 
662
         * If force user is true, then store the given userid and the gid of
 
663
         * the user we're forcing.
 
664
         * For auxiliary groups see below.
405
665
         */
406
666
        
407
667
        if (*lp_force_user(snum)) {
408
 
                struct passwd *pass2;
409
 
                pstring fuser;
410
 
                pstrcpy(fuser,lp_force_user(snum));
411
 
 
412
 
                /* Allow %S to be used by force user. */
413
 
                pstring_sub(fuser,"%S",lp_servicename(snum));
414
 
 
415
 
                pass2 = (struct passwd *)Get_Pwnam(fuser);
416
 
                if (pass2) {
417
 
                        conn->uid = pass2->pw_uid;
418
 
                        conn->gid = pass2->pw_gid;
419
 
                        string_set(&conn->user,pass2->pw_name);
420
 
                        fstrcpy(user,pass2->pw_name);
421
 
                        conn->force_user = True;
422
 
                        DEBUG(3,("Forced user %s\n",user));       
423
 
                } else {
424
 
                        DEBUG(1,("Couldn't find user %s\n",fuser));
 
668
                NTSTATUS status2;
 
669
 
 
670
                status2 = find_forced_user(snum,
 
671
                                           (vuser != NULL) && vuser->guest,
 
672
                                           &conn->uid, &conn->gid, user,
 
673
                                           &conn->nt_user_token);
 
674
                if (!NT_STATUS_IS_OK(status2)) {
425
675
                        conn_free(conn);
426
 
                        *status = NT_STATUS_NO_SUCH_USER;
 
676
                        *status = status2;
427
677
                        return NULL;
428
678
                }
 
679
                string_set(&conn->user,user);
 
680
                conn->force_user = True;
 
681
                DEBUG(3,("Forced user %s\n",user));       
429
682
        }
430
683
 
431
 
#ifdef HAVE_GETGRNAM 
432
684
        /*
433
685
         * If force group is true, then override
434
686
         * any groupid stored for the connecting user.
435
687
         */
436
688
        
437
689
        if (*lp_force_group(snum)) {
438
 
                gid_t gid;
439
 
                pstring gname;
440
 
                pstring tmp_gname;
441
 
                BOOL user_must_be_member = False;
442
 
                
443
 
                pstrcpy(tmp_gname,lp_force_group(snum));
444
 
                
445
 
                if (tmp_gname[0] == '+') {
446
 
                        user_must_be_member = True;
447
 
                        /* even now, tmp_gname is null terminated */
448
 
                        pstrcpy(gname,&tmp_gname[1]);
449
 
                } else {
450
 
                        pstrcpy(gname,tmp_gname);
451
 
                }
452
 
                /* default service may be a group name          */
453
 
                pstring_sub(gname,"%S",lp_servicename(snum));
454
 
                gid = nametogid(gname);
455
 
                
456
 
                if (gid == (gid_t)-1) {
457
 
                        DEBUG(1,("Couldn't find group %s\n",gname));
 
690
                NTSTATUS status2;
 
691
                DOM_SID group_sid;
 
692
 
 
693
                status2 = find_forced_group(conn->force_user,
 
694
                                            snum, user,
 
695
                                            &group_sid, &conn->gid);
 
696
                if (!NT_STATUS_IS_OK(status2)) {
458
697
                        conn_free(conn);
459
 
                        *status = NT_STATUS_NO_SUCH_GROUP;
 
698
                        *status = status2;
460
699
                        return NULL;
461
700
                }
462
701
 
463
 
                        /*
464
 
                         * If the user has been forced and the forced group starts
465
 
                         * with a '+', then we only set the group to be the forced
466
 
                         * group if the forced user is a member of that group.
467
 
                         * Otherwise, the meaning of the '+' would be ignored.
468
 
                         */
469
 
                        if (conn->force_user && user_must_be_member) {
470
 
                                if (user_in_group_list( user, gname, NULL, 0)) {
471
 
                                                conn->gid = gid;
472
 
                                DEBUG(3,("Forced group %s for member %s\n",
473
 
                                         gname,user));
474
 
                                }
475
 
                        } else {
476
 
                                conn->gid = gid;
477
 
                                DEBUG(3,("Forced group %s\n",gname));
478
 
                        }
479
 
                        conn->force_group = True;
480
 
        }
481
 
#endif /* HAVE_GETGRNAM */
 
702
                if ((conn->nt_user_token == NULL) && (vuser != NULL)) {
 
703
 
 
704
                        /* Not force user and not security=share, but force
 
705
                         * group. vuser has a token to copy */
 
706
                        
 
707
                        conn->nt_user_token = dup_nt_token(
 
708
                                NULL, vuser->nt_user_token);
 
709
                        if (conn->nt_user_token == NULL) {
 
710
                                DEBUG(0, ("dup_nt_token failed\n"));
 
711
                                conn_free(conn);
 
712
                                *status = NT_STATUS_NO_MEMORY;
 
713
                                return NULL;
 
714
                        }
 
715
                }
 
716
 
 
717
                /* If conn->nt_user_token is still NULL, we have
 
718
                 * security=share. This means ignore the SID, as we had no
 
719
                 * vuser to copy from */
 
720
 
 
721
                if (conn->nt_user_token != NULL) {
 
722
                        /* Overwrite the primary group sid */
 
723
                        sid_copy(&conn->nt_user_token->user_sids[1],
 
724
                                 &group_sid);
 
725
 
 
726
                }
 
727
                conn->force_group = True;
 
728
        }
 
729
 
 
730
        if (conn->nt_user_token != NULL) {
 
731
                size_t i;
 
732
 
 
733
                /* We have a share-specific token from force [user|group].
 
734
                 * This means we have to create the list of unix groups from
 
735
                 * the list of sids. */
 
736
 
 
737
                conn->ngroups = 0;
 
738
                conn->groups = NULL;
 
739
 
 
740
                for (i=0; i<conn->nt_user_token->num_sids; i++) {
 
741
                        gid_t gid;
 
742
                        DOM_SID *sid = &conn->nt_user_token->user_sids[i];
 
743
 
 
744
                        if (!sid_to_gid(sid, &gid)) {
 
745
                                DEBUG(10, ("Could not convert SID %s to gid, "
 
746
                                           "ignoring it\n",
 
747
                                           sid_string_static(sid)));
 
748
                                continue;
 
749
                        }
 
750
                        add_gid_to_array_unique(NULL, gid, &conn->groups,
 
751
                                                &conn->ngroups);
 
752
                }
 
753
        }
482
754
 
483
755
        {
484
756
                pstring s;
485
757
                pstrcpy(s,lp_pathname(snum));
486
758
                standard_sub_conn(conn,s,sizeof(s));
487
 
                string_set(&conn->connectpath,s);
488
 
                DEBUG(3,("Connect path is '%s' for service [%s]\n",s, lp_servicename(snum)));
489
 
        }
490
 
 
491
 
        if (conn->force_user || conn->force_group) {
492
 
 
493
 
                /* groups stuff added by ih */
494
 
                conn->ngroups = 0;
495
 
                conn->groups = NULL;
496
 
                
497
 
                /* Find all the groups this uid is in and
498
 
                   store them. Used by change_to_user() */
499
 
                initialise_groups(conn->user, conn->uid, conn->gid); 
500
 
                get_current_groups(conn->gid, &conn->ngroups,&conn->groups);
501
 
                
502
 
                conn->nt_user_token = create_nt_token(conn->uid, conn->gid, 
503
 
                                                      conn->ngroups, conn->groups,
504
 
                                                      guest);
 
759
                set_conn_connectpath(conn,s);
 
760
                DEBUG(3,("Connect path is '%s' for service [%s]\n",s,
 
761
                         lp_servicename(snum)));
505
762
        }
506
763
 
507
764
        /*
552
809
                pstring s;
553
810
                pstrcpy(s,conn->connectpath);
554
811
                canonicalize_path(conn, s);
555
 
                string_set(&conn->connectpath,s);
 
812
                set_conn_connectpath(conn,s);
556
813
        }
557
814
 
558
815
/* ROOT Activities: */  
601
858
        
602
859
        /* Preexecs are done here as they might make the dir we are to ChDir
603
860
         * to below */
604
 
        
 
861
 
605
862
        /* execute any "preexec = " line */
606
863
        if (*lp_preexec(snum)) {
607
864
                pstring cmd;
679
936
                pstring s;
680
937
                pstrcpy(s,conn->connectpath);
681
938
                vfs_GetWd(conn,s);
682
 
                string_set(&conn->connectpath,s);
 
939
                set_conn_connectpath(conn,s);
683
940
                vfs_ChDir(conn,conn->connectpath);
684
941
        }
685
942
#endif
700
957
                dbgtext( "(pid %d)\n", (int)sys_getpid() );
701
958
        }
702
959
        
 
960
        /* Setup the minimum value for a change notify wait time (seconds). */
 
961
        set_change_notify_timeout(lp_change_notify_timeout(snum));
 
962
 
703
963
        /* we've finished with the user stuff - go back to root */
704
964
        change_to_root_user();
705
965
        return(conn);
763
1023
                smb_panic("make_connection: PANIC ERROR. Called as nonroot\n");
764
1024
        }
765
1025
 
 
1026
        if (conn_num_open() > 2047) {
 
1027
                *status = NT_STATUS_INSUFF_SERVER_RESOURCES;
 
1028
                return NULL;
 
1029
        }
 
1030
 
766
1031
        if(lp_security() != SEC_SHARE) {
767
1032
                vuser = get_valid_user_struct(vuid);
768
1033
                if (!vuser) {