*/
#include "includes.h"
+#include "smbd/globals.h"
extern userdom_struct current_user_info;
const char *s = connectpath;
bool start_of_name_component = true;
- destname = SMB_STRDUP(connectpath);
+ if (connectpath == NULL || connectpath[0] == '\0') {
+ return false;
+ }
+
+ /* Allocate for strlen + '\0' + possible leading '/' */
+ destname = SMB_MALLOC(strlen(connectpath) + 2);
if (!destname) {
return false;
}
bool set_current_service(connection_struct *conn, uint16 flags, bool do_chdir)
{
- static connection_struct *last_conn;
- static uint16 last_flags;
int snum;
if (!conn) {
if (do_chdir &&
vfs_ChDir(conn,conn->connectpath) != 0 &&
vfs_ChDir(conn,conn->origpath) != 0) {
- DEBUG(0,("chdir (%s) failed\n",
- conn->connectpath));
+ DEBUG(((errno!=EACCES)?0:3),("chdir (%s) failed, reason: %s\n",
+ conn->connectpath, strerror(errno)));
return(False);
}
static int load_registry_service(const char *servicename)
{
- struct registry_key *key;
- char *path;
- WERROR err;
-
- uint32 i;
- char *value_name;
- struct registry_value *value;
-
- int res = -1;
-
if (!lp_registry_shares()) {
return -1;
}
- if (strequal(servicename, GLOBAL_NAME)) {
- return -2;
- }
-
- if (asprintf(&path, "%s\\%s", KEY_SMBCONF, servicename) == -1) {
- return -1;
- }
-
- err = reg_open_path(NULL, path, REG_KEY_READ, get_root_nt_token(),
- &key);
- SAFE_FREE(path);
-
- if (!W_ERROR_IS_OK(err)) {
+ if ((servicename == NULL) || (*servicename == '\0')) {
return -1;
}
- res = lp_add_service(servicename, -1);
- if (res == -1) {
- goto error;
+ if (strequal(servicename, GLOBAL_NAME)) {
+ return -2;
}
- for (i=0;
- W_ERROR_IS_OK(reg_enumvalue(key, key, i, &value_name, &value));
- i++) {
- switch (value->type) {
- case REG_DWORD: {
- char *tmp;
- if (asprintf(&tmp, "%d", value->v.dword) == -1) {
- continue;
- }
- lp_do_parameter(res, value_name, tmp);
- SAFE_FREE(tmp);
- break;
- }
- case REG_SZ: {
- lp_do_parameter(res, value_name, value->v.sz.str);
- break;
- }
- default:
- /* Ignore all the rest */
- break;
- }
-
- TALLOC_FREE(value_name);
- TALLOC_FREE(value);
+ if (!process_registry_service(servicename)) {
+ return -1;
}
- error:
-
- TALLOC_FREE(key);
- return res;
+ return lp_servicenumber(servicename);
}
void load_registry_shares(void)
{
- struct registry_key *key;
- char *name;
- WERROR err;
- int i;
-
DEBUG(8, ("load_registry_shares()\n"));
if (!lp_registry_shares()) {
return;
}
- err = reg_open_path(NULL, KEY_SMBCONF, REG_KEY_READ,
- get_root_nt_token(), &key);
- if (!(W_ERROR_IS_OK(err))) {
- return;
- }
-
- for (i=0; W_ERROR_IS_OK(reg_enumkey(key, key, i, &name, NULL)); i++) {
- load_registry_service(name);
- TALLOC_FREE(name);
- }
+ process_registry_shares();
- TALLOC_FREE(key);
return;
}
{
int iHomeService;
- if (!service || !homedir)
+ if (!service || !homedir || homedir[0] == '\0')
return -1;
if ((iHomeService = lp_servicenumber(HOMES_NAME)) < 0) {
int find_service(fstring service)
{
int iService;
+ struct smbd_server_connection *sconn = smbd_server_conn;
all_string_sub(service,"\\","/",0);
* Try mapping the servicename, it may
* be a Windows to unix mapped user name.
*/
- if(map_username(service))
+ if(map_username(sconn, service))
phome_dir = get_user_home_dir(
talloc_tos(), service);
}
Create an auth_serversupplied_info structure for a connection_struct
****************************************************************************/
-static NTSTATUS create_connection_server_info(TALLOC_CTX *mem_ctx, int snum,
+static NTSTATUS create_connection_server_info(struct smbd_server_connection *sconn,
+ TALLOC_CTX *mem_ctx, int snum,
struct auth_serversupplied_info *vuid_serverinfo,
DATA_BLOB password,
struct auth_serversupplied_info **presult)
/* add the sharename as a possible user name if we
are in share mode security */
- add_session_user(lp_servicename(snum));
+ add_session_user(sconn, lp_servicename(snum));
/* shall we let them in? */
- if (!authorise_login(snum,user,password,&guest)) {
+ if (!authorise_login(sconn, snum,user,password,&guest)) {
DEBUG( 2, ( "Invalid username/password for [%s]\n",
lp_servicename(snum)) );
return NT_STATUS_WRONG_PASSWORD;
connecting user if appropriate.
****************************************************************************/
-static connection_struct *make_connection_snum(int snum, user_struct *vuser,
- DATA_BLOB password,
- const char *pdev,
- NTSTATUS *pstatus)
+connection_struct *make_connection_snum(struct smbd_server_connection *sconn,
+ int snum, user_struct *vuser,
+ DATA_BLOB password,
+ const char *pdev,
+ NTSTATUS *pstatus)
{
connection_struct *conn;
- SMB_STRUCT_STAT st;
+ struct smb_filename *smb_fname_cpath = NULL;
fstring dev;
int ret;
char addr[INET6_ADDRSTRLEN];
NTSTATUS status;
fstrcpy(dev, pdev);
- SET_STAT_INVALID(st);
if (NT_STATUS_IS_ERR(*pstatus = share_sanity_checks(snum, dev))) {
return NULL;
}
- conn = conn_new();
+ conn = conn_new(sconn);
if (!conn) {
DEBUG(0,("Couldn't find free connection.\n"));
*pstatus = NT_STATUS_INSUFFICIENT_RESOURCES;
conn->params->service = snum;
- status = create_connection_server_info(
+ status = create_connection_server_info(sconn,
conn, snum, vuser ? vuser->server_info : NULL, password,
&conn->server_info);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("create_connection_server_info failed: %s\n",
+ DEBUG(1, ("create_connection_server_info failed: %s\n",
nt_errstr(status)));
*pstatus = status;
conn_free(conn);
conn->force_user = true;
}
- add_session_user(conn->server_info->unix_name);
+ add_session_user(sconn, conn->server_info->unix_name);
safe_strcpy(conn->client_address,
client_addr(get_client_fd(),addr,sizeof(addr)),
conn->printer = (strncmp(dev,"LPT",3) == 0);
conn->ipc = ( (strncmp(dev,"IPC",3) == 0) ||
( lp_enable_asu_support() && strequal(dev,"ADMIN$")) );
- conn->dirptr = NULL;
/* Case options for the share. */
if (lp_casesensitive(snum) == Auto) {
conn->hide_list = NULL;
conn->veto_oplock_list = NULL;
conn->aio_write_behind_list = NULL;
- string_set(&conn->dirpath,"");
conn->read_only = lp_readonly(SNUM(conn));
conn->admin_user = False;
*pstatus = status;
return NULL;
}
+
+ /*
+ * We need to cache this gid, to use within
+ * change_to_user() separately from the conn->server_info
+ * struct. We only use conn->server_info directly if
+ * "force_user" was set.
+ */
+ conn->force_group_gid = conn->server_info->utok.gid;
}
conn->vuid = (vuser != NULL) ? vuser->vuid : UID_FIELD_INVALID;
/* Any error exit after here needs to call the disconnect hook. */
on_err_call_dis_hook = true;
+ status = create_synthetic_smb_fname(talloc_tos(), conn->connectpath,
+ NULL, NULL, &smb_fname_cpath);
+ if (!NT_STATUS_IS_OK(status)) {
+ *pstatus = status;
+ goto err_root_exit;
+ }
+
/* win2000 does not check the permissions on the directory
during the tree connect, instead relying on permission
check during individual operations. To match this behaviour
I have disabled this chdir check (tridge) */
/* the alternative is just to check the directory exists */
- if ((ret = SMB_VFS_STAT(conn, conn->connectpath, &st)) != 0 ||
- !S_ISDIR(st.st_mode)) {
- if (ret == 0 && !S_ISDIR(st.st_mode)) {
+ if ((ret = SMB_VFS_STAT(conn, smb_fname_cpath)) != 0 ||
+ !S_ISDIR(smb_fname_cpath->st.st_ex_mode)) {
+ if (ret == 0 && !S_ISDIR(smb_fname_cpath->st.st_ex_mode)) {
DEBUG(0,("'%s' is not a directory, when connecting to "
"[%s]\n", conn->connectpath,
lp_servicename(snum)));
}
#endif
+ if (lp_unix_extensions() && lp_widelinks(snum)) {
+ DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
+ "These parameters are incompatible. "
+ "Disabling wide links for this share.\n",
+ lp_servicename(snum) ));
+ lp_do_parameter(snum, "wide links", "False");
+ }
+
/* Figure out the characteristics of the underlying filesystem. This
* assumes that all the filesystem mounted withing a share path have
* the same characteristics, which is likely but not guaranteed.
*/
- conn->fs_capabilities = SMB_VFS_FS_CAPABILITIES(conn);
+ conn->fs_capabilities = SMB_VFS_FS_CAPABILITIES(conn, &conn->ts_res);
/*
* Print out the 'connected as' stuff here as we need
if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) {
dbgtext( "%s (%s) ", get_remote_machine_name(),
conn->client_address );
- dbgtext( "%s", srv_is_signing_active() ? "signed " : "");
+ dbgtext( "%s", srv_is_signing_active(smbd_server_conn) ? "signed " : "");
dbgtext( "connect to service %s ", lp_servicename(snum) );
dbgtext( "initially as user %s ",
conn->server_info->unix_name );
return(conn);
err_root_exit:
-
+ TALLOC_FREE(smb_fname_cpath);
change_to_root_user();
if (on_err_call_dis_hook) {
/* Call VFS disconnect hook */
* @param service
****************************************************************************/
-connection_struct *make_connection(const char *service_in, DATA_BLOB password,
+connection_struct *make_connection(struct smbd_server_connection *sconn,
+ const char *service_in, DATA_BLOB password,
const char *pdev, uint16 vuid,
NTSTATUS *status)
{
smb_panic("make_connection: PANIC ERROR. Called as nonroot\n");
}
- if (conn_num_open() > 2047) {
+ if (conn_num_open(sconn) > 2047) {
*status = NT_STATUS_INSUFF_SERVER_RESOURCES;
return NULL;
}
if(lp_security() != SEC_SHARE) {
- vuser = get_valid_user_struct(vuid);
+ vuser = get_valid_user_struct(sconn, vuid);
if (!vuser) {
DEBUG(1,("make_connection: refusing to connect with "
"no session setup\n"));
}
DEBUG(5, ("making a connection to [homes] service "
"created at session setup time\n"));
- return make_connection_snum(vuser->homes_snum,
+ return make_connection_snum(sconn,
+ vuser->homes_snum,
vuser, no_pw,
dev, status);
} else {
fstring unix_username;
fstrcpy(unix_username,
current_user_info.smb_name);
- map_username(unix_username);
+ map_username(sconn, unix_username);
snum = find_service(unix_username);
}
if (snum != -1) {
DEBUG(5, ("making a connection to 'homes' "
"service %s based on "
"security=share\n", service_in));
- return make_connection_snum(snum, NULL,
+ return make_connection_snum(sconn,
+ snum, NULL,
password,
dev, status);
}
DATA_BLOB no_pw = data_blob_null;
DEBUG(5, ("making a connection to 'homes' service [%s] "
"created at session setup time\n", service_in));
- return make_connection_snum(vuser->homes_snum,
+ return make_connection_snum(sconn,
+ vuser->homes_snum,
vuser, no_pw,
dev, status);
}
return NULL;
}
- DEBUG(0,("%s (%s) couldn't find service %s\n",
+ DEBUG(3,("%s (%s) couldn't find service %s\n",
get_remote_machine_name(),
client_addr(get_client_fd(),addr,sizeof(addr)),
service));
DEBUG(5, ("making a connection to 'normal' service %s\n", service));
- return make_connection_snum(snum, vuser,
+ return make_connection_snum(sconn, snum, vuser,
password,
dev, status);
}