extern userdom_struct current_user_info;
-static bool canonicalize_path(connection_struct *conn, pstring path)
+static bool canonicalize_connect_path(connection_struct *conn)
{
#ifdef REALPATH_TAKES_NULL
- char *resolved_name = SMB_VFS_REALPATH(conn,path,NULL);
+ bool ret;
+ char *resolved_name = SMB_VFS_REALPATH(conn,conn->connectpath,NULL);
if (!resolved_name) {
- return False;
+ return false;
}
- pstrcpy(path, resolved_name);
+ ret = set_conn_connectpath(conn,resolved_name);
SAFE_FREE(resolved_name);
- return True;
+ return ret;
#else
-#ifdef PATH_MAX
char resolved_name_buf[PATH_MAX+1];
-#else
- pstring resolved_name_buf;
-#endif
- char *resolved_name = SMB_VFS_REALPATH(conn,path,resolved_name_buf);
+ char *resolved_name = SMB_VFS_REALPATH(conn,conn->connectpath,resolved_name_buf);
if (!resolved_name) {
- return False;
+ return false;
}
- pstrcpy(path, resolved_name);
- return True;
+ return set_conn_connectpath(conn,resolved_name);
#endif /* REALPATH_TAKES_NULL */
}
Observent people will notice a similarity between this and check_path_syntax :-).
****************************************************************************/
-void set_conn_connectpath(connection_struct *conn, const char *connectpath)
+bool set_conn_connectpath(connection_struct *conn, const char *connectpath)
{
- pstring destname;
- char *d = destname;
+ char *destname;
+ char *d;
const char *s = connectpath;
- bool start_of_name_component = True;
+ bool start_of_name_component = true;
+
+ destname = SMB_STRDUP(connectpath);
+ if (!destname) {
+ return false;
+ }
+ d = destname;
*d++ = '/'; /* Always start with root. */
break;
}
}
- start_of_name_component = False;
+ start_of_name_component = false;
}
*d = '\0';
lp_servicename(SNUM(conn)), destname ));
string_set(&conn->connectpath, destname);
+ SAFE_FREE(destname);
+ return true;
}
/****************************************************************************
return(True);
}
-/****************************************************************************
- Add a home service. Returns the new service number or -1 if fail.
-****************************************************************************/
-
-int add_home_service(const char *service, const char *username, const char *homedir)
-{
- int iHomeService;
-
- if (!service || !homedir)
- return -1;
-
- if ((iHomeService = lp_servicenumber(HOMES_NAME)) < 0)
- return -1;
-
- /*
- * If this is a winbindd provided username, remove
- * the domain component before adding the service.
- * Log a warning if the "path=" parameter does not
- * include any macros.
- */
-
- {
- const char *p = strchr(service,*lp_winbind_separator());
-
- /* We only want the 'user' part of the string */
- if (p) {
- service = p + 1;
- }
- }
-
- if (!lp_add_home(service, iHomeService, username, homedir)) {
- return -1;
- }
-
- return lp_servicenumber(service);
-
-}
-
static int load_registry_service(const char *servicename)
{
struct registry_key *key;
TALLOC_FREE(value);
}
- res = 0;
error:
TALLOC_FREE(key);
return;
}
+/****************************************************************************
+ Add a home service. Returns the new service number or -1 if fail.
+****************************************************************************/
+
+int add_home_service(const char *service, const char *username, const char *homedir)
+{
+ int iHomeService;
+
+ if (!service || !homedir)
+ return -1;
+
+ if ((iHomeService = lp_servicenumber(HOMES_NAME)) < 0) {
+ if ((iHomeService = load_registry_service(HOMES_NAME)) < 0) {
+ return -1;
+ }
+ }
+
+ /*
+ * If this is a winbindd provided username, remove
+ * the domain component before adding the service.
+ * Log a warning if the "path=" parameter does not
+ * include any macros.
+ */
+
+ {
+ const char *p = strchr(service,*lp_winbind_separator());
+
+ /* We only want the 'user' part of the string */
+ if (p) {
+ service = p + 1;
+ }
+ }
+
+ if (!lp_add_home(service, iHomeService, username, homedir)) {
+ return -1;
+ }
+
+ return lp_servicenumber(service);
+
+}
+
/**
* Find a service entry.
*
/* now handle the special case of a home directory */
if (iService < 0) {
- char *phome_dir = get_user_home_dir(service);
+ char *phome_dir = get_user_home_dir(talloc_tos(), service);
if(!phome_dir) {
/*
* be a Windows to unix mapped user name.
*/
if(map_username(service))
- phome_dir = get_user_home_dir(service);
+ phome_dir = get_user_home_dir(
+ talloc_tos(), service);
}
DEBUG(3,("checking for home directory %s gave %s\n",service,
if (iService < 0) {
int iPrinterService;
- if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0) {
+ if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) < 0) {
+ iPrinterService = load_registry_service(PRINTERS_NAME);
+ }
+ if (iPrinterService) {
DEBUG(3,("checking whether %s is a valid printer name...\n", service));
if (pcap_printername_ok(service)) {
DEBUG(3,("%s is a valid printer name\n", service));
* could get overwritten by the recursive find_service() call
* below. Fix from Josef Hinteregger <joehtg@joehtg.co.at>.
*/
- pstring defservice;
- pstrcpy(defservice, pdefservice);
+ char *defservice = SMB_STRDUP(pdefservice);
+
+ if (!defservice) {
+ goto fail;
+ }
/* Disallow anything except explicit share names. */
if (strequal(defservice,HOMES_NAME) ||
strequal(defservice, PRINTERS_NAME) ||
strequal(defservice, "IPC$")) {
+ SAFE_FREE(defservice);
goto fail;
}
all_string_sub(service, "_","/",0);
iService = lp_add_service(service, iService);
}
+ SAFE_FREE(defservice);
}
}
if (!sid_to_gid(&group_sid, &gid)) {
DEBUG(10, ("sid_to_gid(%s) for %s failed\n",
- sid_string_static(&group_sid), groupname));
+ sid_string_dbg(&group_sid), groupname));
goto done;
}
fstring dev;
int ret;
char addr[INET6_ADDRSTRLEN];
+ bool on_err_call_dis_hook = false;
*user = 0;
fstrcpy(dev, pdev);
*status = NT_STATUS_WRONG_PASSWORD;
return NULL;
}
- pass = Get_Pwnam(user);
+ pass = Get_Pwnam_alloc(talloc_tos(), user);
status2 = create_token_from_username(conn->mem_ctx, pass->pw_name, True,
&conn->uid, &conn->gid,
&found_username,
&conn->nt_user_token);
+ TALLOC_FREE(pass);
if (!NT_STATUS_IS_OK(status2)) {
conn_free(conn);
*status = status2;
add_session_user(user);
- safe_strcpy(conn->client_address, client_addr(addr,sizeof(addr)),
- sizeof(conn->client_address)-1);
+ safe_strcpy(conn->client_address,
+ client_addr(get_client_fd(),addr,sizeof(addr)),
+ sizeof(conn->client_address)-1);
conn->num_files_open = 0;
conn->lastused = conn->lastused_count = time(NULL);
conn->used = True;
conn->case_preserve = lp_preservecase(snum);
conn->short_case_preserve = lp_shortpreservecase(snum);
+ conn->encrypt_level = lp_smb_encrypt(snum);
+
conn->veto_list = NULL;
conn->hide_list = NULL;
conn->veto_oplock_list = NULL;
if (!sid_to_gid(sid, &gid)) {
DEBUG(10, ("Could not convert SID %s to gid, "
"ignoring it\n",
- sid_string_static(sid)));
+ sid_string_dbg(sid)));
continue;
}
if (!add_gid_to_array_unique(conn->mem_ctx, gid, &conn->groups,
}
{
- pstring s;
- pstrcpy(s,lp_pathname(snum));
- standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
- conn->connectpath, conn->gid,
- get_current_username(),
- current_user_info.domain,
- s, sizeof(s));
- set_conn_connectpath(conn,s);
+ char *s = talloc_sub_advanced(talloc_tos(),
+ lp_servicename(SNUM(conn)), conn->user,
+ conn->connectpath, conn->gid,
+ get_current_username(),
+ current_user_info.domain,
+ lp_pathname(snum));
+ if (!s) {
+ conn_free(conn);
+ *status = NT_STATUS_NO_MEMORY;
+ return NULL;
+ }
+
+ if (!set_conn_connectpath(conn,s)) {
+ TALLOC_FREE(s);
+ conn_free(conn);
+ *status = NT_STATUS_NO_MEMORY;
+ return NULL;
+ }
DEBUG(3,("Connect path is '%s' for service [%s]\n",s,
lp_servicename(snum)));
+ TALLOC_FREE(s);
}
/*
* depend on the realpath() pointer in the vfs table. JRA.
*/
if (!lp_widelinks(snum)) {
- pstring s;
- pstrcpy(s,conn->connectpath);
- canonicalize_path(conn, s);
- set_conn_connectpath(conn,s);
+ if (!canonicalize_connect_path(conn)) {
+ DEBUG(0, ("canonicalize_connect_path failed "
+ "for service %s, path %s\n",
+ lp_servicename(snum),
+ conn->connectpath));
+ conn_free(conn);
+ *status = NT_STATUS_BAD_NETWORK_NAME;
+ return NULL;
+ }
}
if ((!conn->printer) && (!conn->ipc)) {
* to below */
/* execute any "root preexec = " line */
if (*lp_rootpreexec(snum)) {
- pstring cmd;
- pstrcpy(cmd,lp_rootpreexec(snum));
- standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
- conn->connectpath, conn->gid,
- get_current_username(),
- current_user_info.domain,
- cmd, sizeof(cmd));
+ char *cmd = talloc_sub_advanced(talloc_tos(),
+ lp_servicename(SNUM(conn)), conn->user,
+ conn->connectpath, conn->gid,
+ get_current_username(),
+ current_user_info.domain,
+ lp_rootpreexec(snum));
DEBUG(5,("cmd=%s\n",cmd));
ret = smbrun(cmd,NULL);
+ TALLOC_FREE(cmd);
if (ret != 0 && lp_rootpreexec_close(snum)) {
DEBUG(1,("root preexec gave %d - failing "
"connection\n", ret));
/* execute any "preexec = " line */
if (*lp_preexec(snum)) {
- pstring cmd;
- pstrcpy(cmd,lp_preexec(snum));
- standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
- conn->connectpath, conn->gid,
- get_current_username(),
- current_user_info.domain,
- cmd, sizeof(cmd));
+ char *cmd = talloc_sub_advanced(talloc_tos(),
+ lp_servicename(SNUM(conn)), conn->user,
+ conn->connectpath, conn->gid,
+ get_current_username(),
+ current_user_info.domain,
+ lp_preexec(snum));
ret = smbrun(cmd,NULL);
+ TALLOC_FREE(cmd);
if (ret != 0 && lp_preexec_close(snum)) {
DEBUG(1,("preexec gave %d - failing connection\n",
ret));
- change_to_root_user();
- yield_connection(conn, lp_servicename(snum));
- conn_free(conn);
*status = NT_STATUS_ACCESS_DENIED;
- return NULL;
+ goto err_root_exit;
}
}
if (SMB_VFS_CONNECT(conn, lp_servicename(snum), user) < 0) {
DEBUG(0,("make_connection: VFS make connection failed!\n"));
- change_to_root_user();
- yield_connection(conn, lp_servicename(snum));
- conn_free(conn);
*status = NT_STATUS_UNSUCCESSFUL;
- return NULL;
+ goto err_root_exit;
}
+ /* Any error exit after here needs to call the disconnect hook. */
+ on_err_call_dis_hook = true;
+
/* 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
conn->connectpath, lp_servicename(snum),
strerror(errno) ));
}
- change_to_root_user();
- /* Call VFS disconnect hook */
- SMB_VFS_DISCONNECT(conn);
- yield_connection(conn, lp_servicename(snum));
- conn_free(conn);
*status = NT_STATUS_BAD_NETWORK_NAME;
- return NULL;
+ goto err_root_exit;
}
string_set(&conn->origpath,conn->connectpath);
#if SOFTLINK_OPTIMISATION
/* resolve any soft links early if possible */
if (vfs_ChDir(conn,conn->connectpath) == 0) {
- TALLOC_CTX *ctx = talloc_stackframe();
+ TALLOC_CTX *ctx = talloc_tos();
char *s = vfs_GetWd(ctx,s);
if (!s) {
*status = map_nt_error_from_unix(errno);
- return NULL;
+ goto err_root_exit;
+ }
+ if (!set_conn_connectpath(conn,s)) {
+ *status = NT_STATUS_NO_MEMORY;
+ goto err_root_exit;
}
- set_conn_connectpath(conn,s);
vfs_ChDir(conn,conn->connectpath);
- TALLOC_FREE(ctx);
}
#endif
+ /* 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);
+
/*
* Print out the 'connected as' stuff here as we need
* to know the effective uid and gid we will be using
/* we've finished with the user stuff - go back to root */
change_to_root_user();
return(conn);
+
+ err_root_exit:
+
+ change_to_root_user();
+ if (on_err_call_dis_hook) {
+ /* Call VFS disconnect hook */
+ SMB_VFS_DISCONNECT(conn);
+ }
+ yield_connection(conn, lp_servicename(snum));
+ conn_free(conn);
+ return NULL;
}
/***************************************************************************************
DEBUG(0,("%s (%s) couldn't find service %s\n",
get_remote_machine_name(),
- client_addr(addr,sizeof(addr)),
+ client_addr(get_client_fd(),addr,sizeof(addr)),
service));
*status = NT_STATUS_BAD_NETWORK_NAME;
return NULL;
/* execute any "postexec = " line */
if (*lp_postexec(SNUM(conn)) &&
change_to_user(conn, vuid)) {
- pstring cmd;
- pstrcpy(cmd,lp_postexec(SNUM(conn)));
- standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
- conn->connectpath, conn->gid,
- get_current_username(),
- current_user_info.domain,
- cmd, sizeof(cmd));
+ char *cmd = talloc_sub_advanced(talloc_tos(),
+ lp_servicename(SNUM(conn)), conn->user,
+ conn->connectpath, conn->gid,
+ get_current_username(),
+ current_user_info.domain,
+ lp_postexec(SNUM(conn)));
smbrun(cmd,NULL);
+ TALLOC_FREE(cmd);
change_to_root_user();
}
change_to_root_user();
/* execute any "root postexec = " line */
if (*lp_rootpostexec(SNUM(conn))) {
- pstring cmd;
- pstrcpy(cmd,lp_rootpostexec(SNUM(conn)));
- standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
- conn->connectpath, conn->gid,
- get_current_username(),
- current_user_info.domain,
- cmd, sizeof(cmd));
+ char *cmd = talloc_sub_advanced(talloc_tos(),
+ lp_servicename(SNUM(conn)), conn->user,
+ conn->connectpath, conn->gid,
+ get_current_username(),
+ current_user_info.domain,
+ lp_rootpostexec(SNUM(conn)));
smbrun(cmd,NULL);
+ TALLOC_FREE(cmd);
}
conn_free(conn);