21
21
#include "includes.h"
23
extern struct timeval smb_last_time;
24
23
extern userdom_struct current_user_info;
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
****************************************************************************/
31
void set_conn_connectpath(connection_struct *conn, const pstring connectpath)
35
const char *s = connectpath;
36
BOOL start_of_name_component = True;
38
*d++ = '/'; /* Always start with root. */
42
/* Eat multiple '/' */
46
if ((d > destname + 1) && (*s != '\0')) {
49
start_of_name_component = True;
53
if (start_of_name_component) {
54
if ((s[0] == '.') && (s[1] == '.') && (s[2] == '/' || s[2] == '\0')) {
55
/* Uh oh - "/../" or "/..\0" ! */
57
/* Go past the ../ or .. */
61
s += 2; /* Go past the .. */
64
/* If we just added a '/' - delete it */
65
if ((d > destname) && (*(d-1) == '/')) {
70
/* Are we at the start ? Can't go back further if so. */
72
*d++ = '/'; /* Can't delete root */
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--) {
82
/* We're still at the start of a name component, just the previous one. */
84
} else if ((s[0] == '.') && ((s[1] == '\0') || s[1] == '/')) {
85
/* Component of pathname can't be "." only - skip the '.' . */
98
switch(next_mb_char_size(s)) {
112
start_of_name_component = False;
116
/* And must not end in '/' */
117
if (d > destname + 1 && (*(d-1) == '/')) {
121
DEBUG(10,("set_conn_connectpath: service %s, connectpath = %s\n",
122
lp_servicename(SNUM(conn)), destname ));
124
string_set(&conn->connectpath, destname);
127
/****************************************************************************
27
128
Load parameters specific to a connection/service.
28
129
****************************************************************************/
257
365
return NT_STATUS_OK;
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)
373
char *fuser, *found_username;
376
mem_ctx = talloc_new(NULL);
377
if (mem_ctx == NULL) {
378
DEBUG(0, ("talloc_new failed\n"));
379
return NT_STATUS_NO_MEMORY;
382
fuser = talloc_string_sub(mem_ctx, lp_force_user(snum), "%S",
383
lp_servicename(snum));
385
result = NT_STATUS_NO_MEMORY;
389
result = create_token_from_username(mem_ctx, fuser, vuser_is_guest,
390
uid, gid, &found_username,
392
if (!NT_STATUS_IS_OK(result)) {
396
talloc_steal(NULL, *token);
397
fstrcpy(username, found_username);
399
result = NT_STATUS_OK;
401
TALLOC_FREE(mem_ctx);
406
* Go through lookup_name etc to find the force'd group.
408
* Create a new token from src_token, replacing the primary group sid with the
412
static NTSTATUS find_forced_group(BOOL force_user,
413
int snum, const char *username,
417
NTSTATUS result = NT_STATUS_NO_SUCH_GROUP;
420
enum SID_NAME_USE type;
422
BOOL user_must_be_member = False;
425
ZERO_STRUCTP(pgroup_sid);
428
mem_ctx = talloc_new(NULL);
429
if (mem_ctx == NULL) {
430
DEBUG(0, ("talloc_new failed\n"));
431
return NT_STATUS_NO_MEMORY;
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;
441
if (groupname[0] == '+') {
442
user_must_be_member = True;
446
groupname = talloc_string_sub(mem_ctx, groupname,
447
"%S", lp_servicename(snum));
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",
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)));
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));
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 '+'
477
if (force_user && user_must_be_member) {
478
if (user_in_group_sid(username, &group_sid)) {
479
sid_copy(pgroup_sid, &group_sid);
481
DEBUG(3,("Forced group %s for member %s\n",
482
groupname, username));
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;
491
sid_copy(pgroup_sid, &group_sid);
493
DEBUG(3,("Forced group %s\n", groupname));
496
result = NT_STATUS_OK;
498
TALLOC_FREE(mem_ctx);
260
502
/****************************************************************************
261
503
Make a connection, given the snum to connect to, and the vuser of the
262
504
connecting user if appropriate.
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;
398
658
conn->read_only = lp_readonly(conn->service);
399
659
conn->admin_user = False;
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.
407
667
if (*lp_force_user(snum)) {
408
struct passwd *pass2;
410
pstrcpy(fuser,lp_force_user(snum));
412
/* Allow %S to be used by force user. */
413
pstring_sub(fuser,"%S",lp_servicename(snum));
415
pass2 = (struct passwd *)Get_Pwnam(fuser);
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));
424
DEBUG(1,("Couldn't find user %s\n",fuser));
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)) {
426
*status = NT_STATUS_NO_SUCH_USER;
679
string_set(&conn->user,user);
680
conn->force_user = True;
681
DEBUG(3,("Forced user %s\n",user));
433
685
* If force group is true, then override
434
686
* any groupid stored for the connecting user.
437
689
if (*lp_force_group(snum)) {
441
BOOL user_must_be_member = False;
443
pstrcpy(tmp_gname,lp_force_group(snum));
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]);
450
pstrcpy(gname,tmp_gname);
452
/* default service may be a group name */
453
pstring_sub(gname,"%S",lp_servicename(snum));
454
gid = nametogid(gname);
456
if (gid == (gid_t)-1) {
457
DEBUG(1,("Couldn't find group %s\n",gname));
693
status2 = find_forced_group(conn->force_user,
695
&group_sid, &conn->gid);
696
if (!NT_STATUS_IS_OK(status2)) {
459
*status = NT_STATUS_NO_SUCH_GROUP;
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.
469
if (conn->force_user && user_must_be_member) {
470
if (user_in_group_list( user, gname, NULL, 0)) {
472
DEBUG(3,("Forced group %s for member %s\n",
477
DEBUG(3,("Forced group %s\n",gname));
479
conn->force_group = True;
481
#endif /* HAVE_GETGRNAM */
702
if ((conn->nt_user_token == NULL) && (vuser != NULL)) {
704
/* Not force user and not security=share, but force
705
* group. vuser has a token to copy */
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"));
712
*status = NT_STATUS_NO_MEMORY;
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 */
721
if (conn->nt_user_token != NULL) {
722
/* Overwrite the primary group sid */
723
sid_copy(&conn->nt_user_token->user_sids[1],
727
conn->force_group = True;
730
if (conn->nt_user_token != NULL) {
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. */
740
for (i=0; i<conn->nt_user_token->num_sids; i++) {
742
DOM_SID *sid = &conn->nt_user_token->user_sids[i];
744
if (!sid_to_gid(sid, &gid)) {
745
DEBUG(10, ("Could not convert SID %s to gid, "
747
sid_string_static(sid)));
750
add_gid_to_array_unique(NULL, gid, &conn->groups,
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)));
491
if (conn->force_user || conn->force_group) {
493
/* groups stuff added by ih */
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);
502
conn->nt_user_token = create_nt_token(conn->uid, conn->gid,
503
conn->ngroups, conn->groups,
759
set_conn_connectpath(conn,s);
760
DEBUG(3,("Connect path is '%s' for service [%s]\n",s,
761
lp_servicename(snum)));