F_UNLCK in *ptype if the region is unlocked). False if the call failed.
****************************************************************************/
-bool fcntl_getlock(int fd, off_t *poffset, off_t *pcount, int *ptype, pid_t *ppid)
+bool fcntl_getlock(int fd, int op, off_t *poffset, off_t *pcount, int *ptype, pid_t *ppid)
{
struct flock lock;
int ret;
- DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
- fd,(double)*poffset,(double)*pcount,*ptype));
+ DEBUG(8,("fcntl_getlock fd=%d op=%d offset=%.0f count=%.0f type=%d\n",
+ fd,op,(double)*poffset,(double)*pcount,*ptype));
lock.l_type = *ptype;
lock.l_whence = SEEK_SET;
lock.l_len = *pcount;
lock.l_pid = 0;
- ret = sys_fcntl_ptr(fd,F_GETLK,&lock);
+ ret = sys_fcntl_ptr(fd,op,&lock);
if (ret == -1) {
int sav = errno;
return True;
}
+#if defined(HAVE_OFD_LOCKS)
+int map_process_lock_to_ofd_lock(int op, bool *use_ofd_locks)
+{
+ switch (op) {
+ case F_GETLK:
+ case F_OFD_GETLK:
+ op = F_OFD_GETLK;
+ break;
+ case F_SETLK:
+ case F_OFD_SETLK:
+ op = F_OFD_SETLK;
+ break;
+ case F_SETLKW:
+ case F_OFD_SETLKW:
+ op = F_OFD_SETLKW;
+ break;
+ default:
+ *use_ofd_locks = false;
+ return -1;
+ }
+ *use_ofd_locks = true;
+ return op;
+}
+#else /* HAVE_OFD_LOCKS */
+int map_process_lock_to_ofd_lock(int op, bool *use_ofd_locks)
+{
+ *use_ofd_locks = false;
+ return op;
+}
+#endif /* HAVE_OFD_LOCKS */
+
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_ALL
set_remote_arch( RA_WIN2K3 );
}
-static const char *remote_arch_str;
+static const char *remote_arch_strings[] = {
+ [RA_UNKNOWN] = "UNKNOWN",
+ [RA_WFWG] = "WfWg",
+ [RA_OS2] = "OS2",
+ [RA_WIN95] = "Win95",
+ [RA_WINNT] = "WinNT",
+ [RA_WIN2K] = "Win2K",
+ [RA_WINXP] = "WinXP",
+ [RA_WIN2K3] = "Win2K3",
+ [RA_VISTA] = "Vista",
+ [RA_SAMBA] = "Samba",
+ [RA_CIFSFS] = "CIFSFS",
+ [RA_WINXP64] = "WinXP64",
+ [RA_OSX] = "OSX",
+};
const char *get_remote_arch_str(void)
{
- if (!remote_arch_str) {
- return "UNKNOWN";
+ if (ra_type >= ARRAY_SIZE(remote_arch_strings)) {
+ /*
+ * set_remote_arch() already checks this so ra_type
+ * should be in the allowed range, but anyway, let's
+ * do another bound check here.
+ */
+ DBG_ERR("Remote arch info out of sync [%d] missing\n", ra_type);
+ ra_type = RA_UNKNOWN;
+ }
+ return remote_arch_strings[ra_type];
+}
+
+enum remote_arch_types get_remote_arch_from_str(const char *remote_arch_string)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(remote_arch_strings); i++) {
+ if (strcmp(remote_arch_string, remote_arch_strings[i]) == 0) {
+ return i;
+ }
}
- return remote_arch_str;
+ return RA_UNKNOWN;
}
/*******************************************************************
void set_remote_arch(enum remote_arch_types type)
{
- ra_type = type;
- switch( type ) {
- case RA_WFWG:
- remote_arch_str = "WfWg";
- break;
- case RA_OS2:
- remote_arch_str = "OS2";
- break;
- case RA_WIN95:
- remote_arch_str = "Win95";
- break;
- case RA_WINNT:
- remote_arch_str = "WinNT";
- break;
- case RA_WIN2K:
- remote_arch_str = "Win2K";
- break;
- case RA_WINXP:
- remote_arch_str = "WinXP";
- break;
- case RA_WINXP64:
- remote_arch_str = "WinXP64";
- break;
- case RA_WIN2K3:
- remote_arch_str = "Win2K3";
- break;
- case RA_VISTA:
- remote_arch_str = "Vista";
- break;
- case RA_SAMBA:
- remote_arch_str = "Samba";
- break;
- case RA_CIFSFS:
- remote_arch_str = "CIFSFS";
- break;
- case RA_OSX:
- remote_arch_str = "OSX";
- break;
- default:
+ if (ra_type >= ARRAY_SIZE(remote_arch_strings)) {
+ /*
+ * This protects against someone adding values to enum
+ * remote_arch_types without updating
+ * remote_arch_strings array.
+ */
+ DBG_ERR("Remote arch info out of sync [%d] missing\n", ra_type);
ra_type = RA_UNKNOWN;
- remote_arch_str = "UNKNOWN";
- break;
+ return;
}
+ ra_type = type;
DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n",
- remote_arch_str));
+ get_remote_arch_str()));
}
/*******************************************************************
return ra_type;
}
+#define RA_CACHE_TTL 7*24*3600
+
+static bool remote_arch_cache_key(const struct GUID *client_guid,
+ fstring key)
+{
+ struct GUID_txt_buf guid_buf;
+ const char *guid_string = NULL;
+
+ guid_string = GUID_buf_string(client_guid, &guid_buf);
+ if (guid_string == NULL) {
+ return false;
+ }
+
+ fstr_sprintf(key, "RA/%s", guid_string);
+ return true;
+}
+
+struct ra_parser_state {
+ bool found;
+ enum remote_arch_types ra;
+};
+
+static void ra_parser(time_t timeout, DATA_BLOB blob, void *priv_data)
+{
+ struct ra_parser_state *state = (struct ra_parser_state *)priv_data;
+ const char *ra_str = NULL;
+
+ if (timeout <= time(NULL)) {
+ return;
+ }
+
+ if ((blob.length == 0) || (blob.data[blob.length-1] != '\0')) {
+ DBG_ERR("Remote arch cache key not a string\n");
+ return;
+ }
+
+ ra_str = (const char *)blob.data;
+ DBG_INFO("Got remote arch [%s] from cache\n", ra_str);
+
+ state->ra = get_remote_arch_from_str(ra_str);
+ state->found = true;
+ return;
+}
+
+static bool remote_arch_cache_get(const struct GUID *client_guid)
+{
+ bool ok;
+ fstring ra_key;
+ struct ra_parser_state state = (struct ra_parser_state) {
+ .found = false,
+ .ra = RA_UNKNOWN,
+ };
+
+ ok = remote_arch_cache_key(client_guid, ra_key);
+ if (!ok) {
+ return false;
+ }
+
+ ok = gencache_parse(ra_key, ra_parser, &state);
+ if (!ok || !state.found) {
+ return true;
+ }
+
+ if (state.ra == RA_UNKNOWN) {
+ return true;
+ }
+
+ set_remote_arch(state.ra);
+ return true;
+}
+
+static bool remote_arch_cache_set(const struct GUID *client_guid)
+{
+ bool ok;
+ fstring ra_key;
+ const char *ra_str = NULL;
+
+ if (get_remote_arch() == RA_UNKNOWN) {
+ return true;
+ }
+
+ ok = remote_arch_cache_key(client_guid, ra_key);
+ if (!ok) {
+ return false;
+ }
+
+ ra_str = get_remote_arch_str();
+ if (ra_str == NULL) {
+ return false;
+ }
+
+ ok = gencache_set(ra_key, ra_str, time(NULL) + RA_CACHE_TTL);
+ if (!ok) {
+ return false;
+ }
+
+ return true;
+}
+
+bool remote_arch_cache_update(const struct GUID *client_guid)
+{
+ bool ok;
+
+ if (get_remote_arch() == RA_UNKNOWN) {
+
+ become_root();
+ ok = remote_arch_cache_get(client_guid);
+ unbecome_root();
+
+ return ok;
+ }
+
+ become_root();
+ ok = remote_arch_cache_set(client_guid);
+ unbecome_root();
+
+ return ok;
+}
+
+bool remote_arch_cache_delete(const struct GUID *client_guid)
+{
+ bool ok;
+ fstring ra_key;
+
+ ok = remote_arch_cache_key(client_guid, ra_key);
+ if (!ok) {
+ return false;
+ }
+
+ become_root();
+ ok = gencache_del(ra_key);
+ unbecome_root();
+
+ if (!ok) {
+ return false;
+ }
+
+ return true;
+}
+
const char *tab_depth(int level, int depth)
{
if( CHECK_DEBUGLVL(level) ) {
return ret;
}
-/**
- * @brief Returns an absolute path to a file concatenating the provided
- * @a rootpath and @a basename
- *
- * @param name Filename, relative to @a rootpath
- *
- * @retval Pointer to a string containing the full path.
- **/
-
-static char *xx_path(const char *name, const char *rootpath)
-{
- char *fname = NULL;
-
- fname = talloc_strdup(talloc_tos(), rootpath);
- if (!fname) {
- return NULL;
- }
- trim_string(fname,"","/");
-
- if (!directory_exist(fname)) {
- if (mkdir(fname,0755) == -1) {
- /* Did someone else win the race ? */
- if (errno != EEXIST) {
- DEBUG(1, ("Unable to create directory %s for file %s. "
- "Error was %s\n", fname, name, strerror(errno)));
- return NULL;
- }
- }
- }
-
- return talloc_asprintf_append(fname, "/%s", name);
-}
-
-/**
- * @brief Returns an absolute path to a file in the Samba lock directory.
- *
- * @param name File to find, relative to LOCKDIR.
- *
- * @retval Pointer to a talloc'ed string containing the full path.
- **/
-
-char *lock_path(const char *name)
-{
- return xx_path(name, lp_lock_directory());
-}
-
-/**
- * @brief Returns an absolute path to a file in the Samba state directory.
- *
- * @param name File to find, relative to STATEDIR.
- *
- * @retval Pointer to a talloc'ed string containing the full path.
- **/
-
-char *state_path(const char *name)
-{
- return xx_path(name, lp_state_directory());
-}
-
-/**
- * @brief Returns an absolute path to a file in the Samba cache directory.
- *
- * @param name File to find, relative to CACHEDIR.
- *
- * @retval Pointer to a talloc'ed string containing the full path.
- **/
-
-char *cache_path(const char *name)
-{
- return xx_path(name, lp_cache_directory());
-}
-
/*******************************************************************
Given a filename - get its directory name
********************************************************************/
{
char c;
- if (lp_posix_pathnames()) {
- /* With posix pathnames no characters are wild. */
- return False;
- }
-
while ((c = *s++)) {
switch (c) {
case '*':
return true;
}
-/**********************************************************************
- Append a DATA_BLOB to a talloc'ed object
-***********************************************************************/
-
-void *talloc_append_blob(TALLOC_CTX *mem_ctx, void *buf, DATA_BLOB blob)
-{
- size_t old_size = 0;
- char *result;
-
- if (blob.length == 0) {
- return buf;
- }
-
- if (buf != NULL) {
- old_size = talloc_get_size(buf);
- }
-
- result = (char *)TALLOC_REALLOC(mem_ctx, buf, old_size + blob.length);
- if (result == NULL) {
- return NULL;
- }
-
- memcpy(result + old_size, blob.data, blob.length);
- return result;
-}
-
uint32_t map_share_mode_to_deny_mode(uint32_t share_access, uint32_t private_options)
{
switch (share_access & ~FILE_SHARE_DELETE) {
return (uint32_t)-1;
}
-pid_t procid_to_pid(const struct server_id *proc)
-{
- return proc->pid;
-}
-
-static uint32_t my_vnn = NONCLUSTER_VNN;
-
-void set_my_vnn(uint32_t vnn)
-{
- DEBUG(10, ("vnn pid %d = %u\n", (int)getpid(), (unsigned int)vnn));
- my_vnn = vnn;
-}
-
-uint32_t get_my_vnn(void)
-{
- return my_vnn;
-}
-
-static uint64_t my_unique_id = 0;
-
-void set_my_unique_id(uint64_t unique_id)
-{
- my_unique_id = unique_id;
-}
-
-struct server_id pid_to_procid(pid_t pid)
-{
- uint64_t unique = 0;
- int ret;
-
- ret = messaging_dgm_get_unique(pid, &unique);
- if (ret != 0) {
- DBG_WARNING("%s: messaging_dgm_get_unique failed: %s\n",
- __func__, strerror(ret));
- }
-
- return (struct server_id) {
- .pid = pid, .unique_id = unique, .vnn = my_vnn };
-}
-
-struct server_id procid_self(void)
-{
- return pid_to_procid(getpid());
-}
-
-bool procid_is_me(const struct server_id *pid)
-{
- if (pid->pid != getpid())
- return False;
- if (pid->task_id != 0)
- return False;
- if (pid->vnn != my_vnn)
- return False;
- return True;
-}
-
struct server_id interpret_pid(const char *pid_string)
{
return server_id_from_string(get_my_vnn(), pid_string);
}
-bool procid_valid(const struct server_id *pid)
-{
- return (pid->pid != (uint64_t)-1);
-}
-
-bool procid_is_local(const struct server_id *pid)
-{
- return pid->vnn == my_vnn;
-}
-
/****************************************************************
Check if an offset into a buffer is safe.
If this returns True it's safe to indirect into the byte at
call (they take care of winbind separator and other winbind specific settings).
****************************************************************/
-void split_domain_user(TALLOC_CTX *mem_ctx,
+bool split_domain_user(TALLOC_CTX *mem_ctx,
const char *full_name,
char **domain,
char **user)
if (p != NULL) {
*domain = talloc_strndup(mem_ctx, full_name,
PTR_DIFF(p, full_name));
+ if (*domain == NULL) {
+ return false;
+ }
*user = talloc_strdup(mem_ctx, p+1);
+ if (*user == NULL) {
+ TALLOC_FREE(*domain);
+ return false;
+ }
} else {
- *domain = talloc_strdup(mem_ctx, "");
+ *domain = NULL;
*user = talloc_strdup(mem_ctx, full_name);
+ if (*user == NULL) {
+ return false;
+ }
}
+
+ return true;
}
/****************************************************************