lib/util: consolidate module loading into common code
[samba.git] / source3 / lib / util.c
index a0b6d9f55d8c9f9d5983740706fdf5d5a7bd2009..f29568fca02ca3f3e787f3e28ea32936f7048773 100644 (file)
 #include "ctdbd_conn.h"
 #include "../lib/util/util_pw.h"
 #include "messages.h"
+#include <ccan/hash/hash.h>
+#include "libcli/security/security.h"
+
+#ifdef HAVE_SYS_PRCTL_H
+#include <sys/prctl.h>
+#endif
 
 /* Max allowable allococation - 256mb - 0x10000000 */
 #define MAX_ALLOC_SIZE (1024*1024*256)
@@ -405,7 +411,7 @@ NTSTATUS reinit_after_fork(struct messaging_context *msg_ctx,
        set_need_random_reseed();
 
        /* tdb needs special fork handling */
-       if (tdb_reopen_all(parent_longlived ? 1 : 0) == -1) {
+       if (tdb_reopen_all(parent_longlived ? 1 : 0) != 0) {
                DEBUG(0,("tdb_reopen_all failed.\n"));
                status = NT_STATUS_OPEN_FAILED;
                goto done;
@@ -776,6 +782,13 @@ void smb_panic_s3(const char *why)
                    (unsigned long long)sys_getpid(), why));
        log_stack_trace();
 
+#if defined(HAVE_PRCTL) && defined(PR_SET_PTRACER)
+       /*
+        * Make sure all children can attach a debugger.
+        */
+       prctl(PR_SET_PTRACER, getpid(), 0, 0, 0);
+#endif
+
        cmd = lp_panic_action();
        if (cmd && *cmd) {
                DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
@@ -1306,8 +1319,9 @@ const char *tab_depth(int level, int depth)
 
 int str_checksum(const char *s)
 {
-       TDB_DATA key = string_tdb_data(s);
-       return tdb_jenkins_hash(&key);
+       if (s == NULL)
+               return 0;
+       return hash(s, strlen(s), 0);
 }
 
 /*****************************************************************
@@ -1456,6 +1470,22 @@ char *myhostname(void)
        return ret;
 }
 
+/*****************************************************************
+ Get local hostname and cache result.
+*****************************************************************/
+
+char *myhostname_upper(void)
+{
+       char *name;
+       static char *ret;
+       if (ret == NULL) {
+               name = get_myname(talloc_tos());
+               ret = strupper_talloc(NULL, name);
+               talloc_free(name);
+       }
+       return ret;
+}
+
 /**
  * @brief Returns an absolute path to a file concatenating the provided
  * @a rootpath and @a basename
@@ -1966,52 +1996,45 @@ bool procid_is_me(const struct server_id *pid)
 struct server_id interpret_pid(const char *pid_string)
 {
        struct server_id result;
-       int pid;
-       unsigned int vnn;
-       if (sscanf(pid_string, "%u:%d", &vnn, &pid) == 2) {
+       unsigned long long pid;
+       unsigned int vnn, task_id = 0;
+
+       ZERO_STRUCT(result);
+
+       /* We accept various forms with 1, 2 or 3 component forms
+        * because the server_id_str() can print different forms, and
+        * we want backwards compatibility for scripts that may call
+        * smbclient. */
+       if (sscanf(pid_string, "%u:%llu.%u", &vnn, &pid, &task_id) == 3) {
                result.vnn = vnn;
                result.pid = pid;
-       }
-       else if (sscanf(pid_string, "%d", &pid) == 1) {
+               result.task_id = task_id;
+       } else if (sscanf(pid_string, "%u:%llu", &vnn, &pid) == 2) {
+               result.vnn = vnn;
+               result.pid = pid;
+               result.task_id = 0;
+       } else if (sscanf(pid_string, "%llu.%u", &pid, &task_id) == 2) {
                result.vnn = get_my_vnn();
                result.pid = pid;
-       }
-       else {
+               result.task_id = task_id;
+       } else if (sscanf(pid_string, "%llu", &pid) == 1) {
+               result.vnn = get_my_vnn();
+               result.pid = pid;
+       } else {
                result.vnn = NONCLUSTER_VNN;
-               result.pid = -1;
+               result.pid = (uint64_t)-1;
        }
-       /* Assigning to result.pid may have overflowed
-          Map negative pid to -1: i.e. error */
-       if (result.pid < 0) {
-               result.pid = -1;
-       }
-       result.unique_id = 0;
        return result;
 }
 
-char *procid_str(TALLOC_CTX *mem_ctx, const struct server_id *pid)
-{
-       if (pid->vnn == NONCLUSTER_VNN) {
-               return talloc_asprintf(mem_ctx,
-                               "%d",
-                               (int)pid->pid);
-       }
-       else {
-               return talloc_asprintf(mem_ctx,
-                                       "%u:%d",
-                                       (unsigned)pid->vnn,
-                                       (int)pid->pid);
-       }
-}
-
 char *procid_str_static(const struct server_id *pid)
 {
-       return procid_str(talloc_tos(), pid);
+       return server_id_str(talloc_tos(), pid);
 }
 
 bool procid_valid(const struct server_id *pid)
 {
-       return (pid->pid != -1);
+       return (pid->pid != (uint64_t)-1);
 }
 
 bool procid_is_local(const struct server_id *pid)
@@ -2227,3 +2250,176 @@ char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
 
        return ptr;
 }
+
+/*******************************************************************
+ Return True if the filename is one of the special executable types.
+********************************************************************/
+
+bool is_executable(const char *fname)
+{
+       if ((fname = strrchr_m(fname,'.'))) {
+               if (strequal(fname,".com") ||
+                   strequal(fname,".dll") ||
+                   strequal(fname,".exe") ||
+                   strequal(fname,".sym")) {
+                       return True;
+               }
+       }
+       return False;
+}
+
+/****************************************************************************
+ Open a file with a share mode - old openX method - map into NTCreate.
+****************************************************************************/
+
+bool map_open_params_to_ntcreate(const char *smb_base_fname,
+                                int deny_mode, int open_func,
+                                uint32 *paccess_mask,
+                                uint32 *pshare_mode,
+                                uint32 *pcreate_disposition,
+                                uint32 *pcreate_options,
+                                uint32_t *pprivate_flags)
+{
+       uint32 access_mask;
+       uint32 share_mode;
+       uint32 create_disposition;
+       uint32 create_options = FILE_NON_DIRECTORY_FILE;
+       uint32_t private_flags = 0;
+
+       DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
+                 "open_func = 0x%x\n",
+                 smb_base_fname, (unsigned int)deny_mode,
+                 (unsigned int)open_func ));
+
+       /* Create the NT compatible access_mask. */
+       switch (GET_OPENX_MODE(deny_mode)) {
+               case DOS_OPEN_EXEC: /* Implies read-only - used to be FILE_READ_DATA */
+               case DOS_OPEN_RDONLY:
+                       access_mask = FILE_GENERIC_READ;
+                       break;
+               case DOS_OPEN_WRONLY:
+                       access_mask = FILE_GENERIC_WRITE;
+                       break;
+               case DOS_OPEN_RDWR:
+               case DOS_OPEN_FCB:
+                       access_mask = FILE_GENERIC_READ|FILE_GENERIC_WRITE;
+                       break;
+               default:
+                       DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n",
+                                 (unsigned int)GET_OPENX_MODE(deny_mode)));
+                       return False;
+       }
+
+       /* Create the NT compatible create_disposition. */
+       switch (open_func) {
+               case OPENX_FILE_EXISTS_FAIL|OPENX_FILE_CREATE_IF_NOT_EXIST:
+                       create_disposition = FILE_CREATE;
+                       break;
+
+               case OPENX_FILE_EXISTS_OPEN:
+                       create_disposition = FILE_OPEN;
+                       break;
+
+               case OPENX_FILE_EXISTS_OPEN|OPENX_FILE_CREATE_IF_NOT_EXIST:
+                       create_disposition = FILE_OPEN_IF;
+                       break;
+
+               case OPENX_FILE_EXISTS_TRUNCATE:
+                       create_disposition = FILE_OVERWRITE;
+                       break;
+
+               case OPENX_FILE_EXISTS_TRUNCATE|OPENX_FILE_CREATE_IF_NOT_EXIST:
+                       create_disposition = FILE_OVERWRITE_IF;
+                       break;
+
+               default:
+                       /* From samba4 - to be confirmed. */
+                       if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_EXEC) {
+                               create_disposition = FILE_CREATE;
+                               break;
+                       }
+                       DEBUG(10,("map_open_params_to_ntcreate: bad "
+                                 "open_func 0x%x\n", (unsigned int)open_func));
+                       return False;
+       }
+
+       /* Create the NT compatible share modes. */
+       switch (GET_DENY_MODE(deny_mode)) {
+               case DENY_ALL:
+                       share_mode = FILE_SHARE_NONE;
+                       break;
+
+               case DENY_WRITE:
+                       share_mode = FILE_SHARE_READ;
+                       break;
+
+               case DENY_READ:
+                       share_mode = FILE_SHARE_WRITE;
+                       break;
+
+               case DENY_NONE:
+                       share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
+                       break;
+
+               case DENY_DOS:
+                       private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;
+                       if (is_executable(smb_base_fname)) {
+                               share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
+                       } else {
+                               if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) {
+                                       share_mode = FILE_SHARE_READ;
+                               } else {
+                                       share_mode = FILE_SHARE_NONE;
+                               }
+                       }
+                       break;
+
+               case DENY_FCB:
+                       private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB;
+                       share_mode = FILE_SHARE_NONE;
+                       break;
+
+               default:
+                       DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n",
+                               (unsigned int)GET_DENY_MODE(deny_mode) ));
+                       return False;
+       }
+
+       DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
+                 "share_mode = 0x%x, create_disposition = 0x%x, "
+                 "create_options = 0x%x private_flags = 0x%x\n",
+                 smb_base_fname,
+                 (unsigned int)access_mask,
+                 (unsigned int)share_mode,
+                 (unsigned int)create_disposition,
+                 (unsigned int)create_options,
+                 (unsigned int)private_flags));
+
+       if (paccess_mask) {
+               *paccess_mask = access_mask;
+       }
+       if (pshare_mode) {
+               *pshare_mode = share_mode;
+       }
+       if (pcreate_disposition) {
+               *pcreate_disposition = create_disposition;
+       }
+       if (pcreate_options) {
+               *pcreate_options = create_options;
+       }
+       if (pprivate_flags) {
+               *pprivate_flags = private_flags;
+       }
+
+       return True;
+
+}
+
+
+void init_modules(void)
+{
+       /* FIXME: This can cause undefined symbol errors :
+        *  smb_register_vfs() isn't available in nmbd, for example */
+       if(lp_preload_modules())
+               smb_load_modules(lp_preload_modules());
+}