示例#1
0
mode_t unix_mode(connection_struct *conn, int dosmode,
		 const struct smb_filename *smb_fname,
		 const char *inherit_from_dir)
{
	mode_t result = (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH);
	mode_t dir_mode = 0; /* Mode of the inherit_from directory if
			      * inheriting. */

	if (!lp_store_dos_attributes(SNUM(conn)) && IS_DOS_READONLY(dosmode)) {
		result &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
	}

	if ((inherit_from_dir != NULL) && lp_inherit_permissions(SNUM(conn))) {
		struct smb_filename *smb_fname_parent;

		DEBUG(2, ("unix_mode(%s) inheriting from %s\n",
			  smb_fname_str_dbg(smb_fname),
			  inherit_from_dir));

		smb_fname_parent = synthetic_smb_fname(
			talloc_tos(), inherit_from_dir, NULL, NULL);
		if (smb_fname_parent == NULL) {
			DEBUG(1,("unix_mode(%s) failed, [dir %s]: No memory\n",
				 smb_fname_str_dbg(smb_fname),
				 inherit_from_dir));
			return(0);
		}

		if (SMB_VFS_STAT(conn, smb_fname_parent) != 0) {
			DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n",
				 smb_fname_str_dbg(smb_fname),
				 inherit_from_dir, strerror(errno)));
			TALLOC_FREE(smb_fname_parent);
			return(0);      /* *** shouldn't happen! *** */
		}

		/* Save for later - but explicitly remove setuid bit for safety. */
		dir_mode = smb_fname_parent->st.st_ex_mode & ~S_ISUID;
		DEBUG(2,("unix_mode(%s) inherit mode %o\n",
			 smb_fname_str_dbg(smb_fname), (int)dir_mode));
		/* Clear "result" */
		result = 0;
		TALLOC_FREE(smb_fname_parent);
	} 

	if (IS_DOS_DIR(dosmode)) {
		/* We never make directories read only for the owner as under DOS a user
		can always create a file in a read-only directory. */
		result |= (S_IFDIR | S_IWUSR);

		if (dir_mode) {
			/* Inherit mode of parent directory. */
			result |= dir_mode;
		} else {
			/* Provisionally add all 'x' bits */
			result |= (S_IXUSR | S_IXGRP | S_IXOTH);                 

			/* Apply directory mask */
			result &= lp_directory_mask(SNUM(conn));
			/* Add in force bits */
			result |= lp_force_directory_mode(SNUM(conn));
		}
	} else { 
		if (lp_map_archive(SNUM(conn)) && IS_DOS_ARCHIVE(dosmode))
			result |= S_IXUSR;

		if (lp_map_system(SNUM(conn)) && IS_DOS_SYSTEM(dosmode))
			result |= S_IXGRP;

		if (lp_map_hidden(SNUM(conn)) && IS_DOS_HIDDEN(dosmode))
			result |= S_IXOTH;  

		if (dir_mode) {
			/* Inherit 666 component of parent directory mode */
			result |= dir_mode & (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH);
		} else {
			/* Apply mode mask */
			result &= lp_create_mask(SNUM(conn));
			/* Add in force bits */
			result |= lp_force_create_mode(SNUM(conn));
		}
	}

	DEBUG(3,("unix_mode(%s) returning 0%o\n", smb_fname_str_dbg(smb_fname),
		 (int)result));
	return(result);
}
/**
 * per-share logic tests
 */
static void do_per_share_checks(int s)
{
	const char **deny_list = lp_hosts_deny(s);
	const char **allow_list = lp_hosts_allow(s);
	int i;

	if(deny_list) {
		for (i=0; deny_list[i]; i++) {
			char *hasstar = strchr_m(deny_list[i], '*');
			char *hasquery = strchr_m(deny_list[i], '?');
			if(hasstar || hasquery) {
				fprintf(stderr,
					"Invalid character %c in hosts deny list "
					"(%s) for service %s.\n\n",
					hasstar ? *hasstar : *hasquery,
					deny_list[i],
					lp_servicename(talloc_tos(), s));
			}
		}
	}

	if(allow_list) {
		for (i=0; allow_list[i]; i++) {
			char *hasstar = strchr_m(allow_list[i], '*');
			char *hasquery = strchr_m(allow_list[i], '?');
			if(hasstar || hasquery) {
				fprintf(stderr,
					"Invalid character %c in hosts allow "
					"list (%s) for service %s.\n\n",
					hasstar ? *hasstar : *hasquery,
					allow_list[i],
					lp_servicename(talloc_tos(), s));
			}
		}
	}

	if(lp_level2_oplocks(s) && !lp_oplocks(s)) {
		fprintf(stderr, "Invalid combination of parameters for service "
				"%s. Level II oplocks can only be set if oplocks "
				"are also set.\n\n",
				lp_servicename(talloc_tos(), s));
	}

	if (!lp_store_dos_attributes(s) && lp_map_hidden(s)
	    && !(lp_create_mask(s) & S_IXOTH))
	{
		fprintf(stderr,
			"Invalid combination of parameters for service %s. Map "
			"hidden can only work if create mask includes octal "
			"01 (S_IXOTH).\n\n",
			lp_servicename(talloc_tos(), s));
	}
	if (!lp_store_dos_attributes(s) && lp_map_hidden(s)
	    && (lp_force_create_mode(s) & S_IXOTH))
	{
		fprintf(stderr,
			"Invalid combination of parameters for service "
			"%s. Map hidden can only work if force create mode "
			"excludes octal 01 (S_IXOTH).\n\n",
			lp_servicename(talloc_tos(), s));
	}
	if (!lp_store_dos_attributes(s) && lp_map_system(s)
	    && !(lp_create_mask(s) & S_IXGRP))
	{
		fprintf(stderr,
			"Invalid combination of parameters for service "
			"%s. Map system can only work if create mask includes "
			"octal 010 (S_IXGRP).\n\n",
			lp_servicename(talloc_tos(), s));
	}
	if (!lp_store_dos_attributes(s) && lp_map_system(s)
	    && (lp_force_create_mode(s) & S_IXGRP))
	{
		fprintf(stderr,
			"Invalid combination of parameters for service "
			"%s. Map system can only work if force create mode "
			"excludes octal 010 (S_IXGRP).\n\n",
			lp_servicename(talloc_tos(), s));
	}
	if (lp_printing(s) == PRINT_CUPS && *(lp_print_command(talloc_tos(), s)) != '\0') {
		fprintf(stderr,
			"Warning: Service %s defines a print command, but "
			"parameter is ignored when using CUPS libraries.\n\n",
			lp_servicename(talloc_tos(), s));
	}
}
示例#3
0
文件: dosmode.c 项目: AllardJ/Tomato
/****************************************************************************
  change a dos mode to a unix mode
    base permission for files:
         if inheriting
           apply read/write bits from parent directory.
         else   
           everybody gets read bit set
         dos readonly is represented in unix by removing everyone's write bit
         dos archive is represented in unix by the user's execute bit
         dos system is represented in unix by the group's execute bit
         dos hidden is represented in unix by the other's execute bit
         if !inheriting {
           Then apply create mask,
           then add force bits.
         }
    base permission for directories:
         dos directory is represented in unix by unix's dir bit and the exec bit
         if !inheriting {
           Then apply create mask,
           then add force bits.
         }
****************************************************************************/
mode_t unix_mode(connection_struct *conn,int dosmode,const char *fname)
{
  mode_t result = (S_IRUSR | S_IRGRP | S_IROTH);
  mode_t dir_mode = 0; /* Mode of the parent directory if inheriting. */

  if ( !IS_DOS_READONLY(dosmode) )
    result |= (S_IWUSR | S_IWGRP | S_IWOTH);

  if (fname && lp_inherit_perms(SNUM(conn))) {
    char *dname;
    SMB_STRUCT_STAT sbuf;

    dname = parent_dirname(fname);
    DEBUG(2,("unix_mode(%s) inheriting from %s\n",fname,dname));
    if (dos_stat(dname,&sbuf) != 0) {
      DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n",fname,dname,strerror(errno)));
      return(0);      /* *** shouldn't happen! *** */
    }

    /* Save for later - but explicitly remove setuid bit for safety. */
    dir_mode = sbuf.st_mode & ~S_ISUID;
    DEBUG(2,("unix_mode(%s) inherit mode %o\n",fname,(int)dir_mode));
    /* Clear "result" */
    result = 0;
  } 

  if (IS_DOS_DIR(dosmode)) {
    /* We never make directories read only for the owner as under DOS a user
       can always create a file in a read-only directory. */
    result |= (S_IFDIR | S_IWUSR);

    if (dir_mode) {
      /* Inherit mode of parent directory. */
      result |= dir_mode;
    } else {
      /* Provisionally add all 'x' bits */
      result |= (S_IXUSR | S_IXGRP | S_IXOTH);                 

      /* Apply directory mask */
      result &= lp_dir_mask(SNUM(conn));
      /* Add in force bits */
      result |= lp_force_dir_mode(SNUM(conn));
    }
  } else { 
    if (lp_map_archive(SNUM(conn)) && IS_DOS_ARCHIVE(dosmode))
      result |= S_IXUSR;

    if (lp_map_system(SNUM(conn)) && IS_DOS_SYSTEM(dosmode))
      result |= S_IXGRP;
 
    if (lp_map_hidden(SNUM(conn)) && IS_DOS_HIDDEN(dosmode))
      result |= S_IXOTH;  

    if (dir_mode) {
      /* Inherit 666 component of parent directory mode */
      result |= dir_mode
        &  (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH);
    } else {
      /* Apply mode mask */
      result &= lp_create_mask(SNUM(conn));
      /* Add in force bits */
      result |= lp_force_create_mode(SNUM(conn));
    }
  }
  return(result);
}
示例#4
0
/**
 * per-share logic tests
 */
static void do_per_share_checks(int s)
{
	const char **deny_list = lp_hosts_deny(s);
	const char **allow_list = lp_hosts_allow(s);
	const char **vfs_objects = NULL;
	int i;
	static bool uses_fruit;
	static bool doesnt_use_fruit;
	static bool fruit_mix_warned;

	if(deny_list) {
		for (i=0; deny_list[i]; i++) {
			char *hasstar = strchr_m(deny_list[i], '*');
			char *hasquery = strchr_m(deny_list[i], '?');
			if(hasstar || hasquery) {
				fprintf(stderr,
					"Invalid character %c in hosts deny list "
					"(%s) for service %s.\n\n",
					hasstar ? *hasstar : *hasquery,
					deny_list[i],
					lp_servicename(talloc_tos(), s));
			}
		}
	}

	if(allow_list) {
		for (i=0; allow_list[i]; i++) {
			char *hasstar = strchr_m(allow_list[i], '*');
			char *hasquery = strchr_m(allow_list[i], '?');
			if(hasstar || hasquery) {
				fprintf(stderr,
					"Invalid character %c in hosts allow "
					"list (%s) for service %s.\n\n",
					hasstar ? *hasstar : *hasquery,
					allow_list[i],
					lp_servicename(talloc_tos(), s));
			}
		}
	}

	if(lp_level2_oplocks(s) && !lp_oplocks(s)) {
		fprintf(stderr, "Invalid combination of parameters for service "
				"%s. Level II oplocks can only be set if oplocks "
				"are also set.\n\n",
				lp_servicename(talloc_tos(), s));
	}

	if (!lp_store_dos_attributes(s) && lp_map_hidden(s)
	    && !(lp_create_mask(s) & S_IXOTH))
	{
		fprintf(stderr,
			"Invalid combination of parameters for service %s. Map "
			"hidden can only work if create mask includes octal "
			"01 (S_IXOTH).\n\n",
			lp_servicename(talloc_tos(), s));
	}
	if (!lp_store_dos_attributes(s) && lp_map_hidden(s)
	    && (lp_force_create_mode(s) & S_IXOTH))
	{
		fprintf(stderr,
			"Invalid combination of parameters for service "
			"%s. Map hidden can only work if force create mode "
			"excludes octal 01 (S_IXOTH).\n\n",
			lp_servicename(talloc_tos(), s));
	}
	if (!lp_store_dos_attributes(s) && lp_map_system(s)
	    && !(lp_create_mask(s) & S_IXGRP))
	{
		fprintf(stderr,
			"Invalid combination of parameters for service "
			"%s. Map system can only work if create mask includes "
			"octal 010 (S_IXGRP).\n\n",
			lp_servicename(talloc_tos(), s));
	}
	if (!lp_store_dos_attributes(s) && lp_map_system(s)
	    && (lp_force_create_mode(s) & S_IXGRP))
	{
		fprintf(stderr,
			"Invalid combination of parameters for service "
			"%s. Map system can only work if force create mode "
			"excludes octal 010 (S_IXGRP).\n\n",
			lp_servicename(talloc_tos(), s));
	}
	if (lp_printing(s) == PRINT_CUPS && *(lp_print_command(talloc_tos(), s)) != '\0') {
		fprintf(stderr,
			"Warning: Service %s defines a print command, but "
			"parameter is ignored when using CUPS libraries.\n\n",
			lp_servicename(talloc_tos(), s));
	}

	vfs_objects = lp_vfs_objects(s);
	if (vfs_objects && str_list_check(vfs_objects, "fruit")) {
		uses_fruit = true;
		if (!lp_ea_support(s) && !lp_ea_support(-1)) {
			fprintf(stderr,
				"ERROR: Service \"%s\" uses vfs_fruit, but "
				"that requires \"ea support = yes\".\n\n",
				lp_servicename(talloc_tos(), s));
		}
	} else {
		doesnt_use_fruit = true;
	}

	if (uses_fruit && doesnt_use_fruit && !fruit_mix_warned) {
		fruit_mix_warned = true;
		fprintf(stderr,
			"WARNING: some services use vfs_fruit, others don't. Mounting them "
			"in conjunction on OS X clients results in undefined behaviour.\n\n");
	}
}