summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs-xml/smbdotconf/security/usernamemapcachetime.xml18
-rw-r--r--source3/include/proto.h1
-rw-r--r--source3/param/loadparm.c11
-rw-r--r--source3/smbd/map_username.c49
4 files changed, 79 insertions, 0 deletions
diff --git a/docs-xml/smbdotconf/security/usernamemapcachetime.xml b/docs-xml/smbdotconf/security/usernamemapcachetime.xml
new file mode 100644
index 0000000000..5461cb1a6c
--- /dev/null
+++ b/docs-xml/smbdotconf/security/usernamemapcachetime.xml
@@ -0,0 +1,18 @@
+<samba:parameter name="username map cache time"
+ context="G"
+ advanced="1" developer="0"
+ type="integer"
+ xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
+<description>
+ <para>This option controls if and how long the result of the
+ <smbconfoption name="username map"/> and
+ <smbconfoption name="username map script"/> across smbds in gencache.
+ If set to non-zero, it denotes the number of seconds the output of
+ both mappings will be cached.</para>
+ <para>This option is mainly useful for heavy-weight
+ <smbconfoption name="username map script"/> scripts.</para>
+</description>
+
+<value type="default">0</value>
+<value type="example">60</value>
+</samba:parameter>
diff --git a/source3/include/proto.h b/source3/include/proto.h
index f1cba8ffa2..71962ae93c 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -3998,6 +3998,7 @@ char *lp_addmachine_script(void);
char *lp_shutdown_script(void);
char *lp_abort_shutdown_script(void);
char *lp_username_map_script(void);
+int lp_username_map_cache_time(void);
char *lp_check_password_script(void);
char *lp_wins_hook(void);
const char *lp_template_homedir(void);
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 077fc6355f..350f3c077c 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -181,6 +181,7 @@ struct global {
char *szShutdownScript;
char *szAbortShutdownScript;
char *szUsernameMapScript;
+ int iUsernameMapCacheTime;
char *szCheckPasswordScript;
char *szWINSHook;
char *szUtmpDir;
@@ -3291,6 +3292,15 @@ static struct parm_struct parm_table[] = {
.flags = FLAG_ADVANCED,
},
{
+ .label = "username map cache time",
+ .type = P_INTEGER,
+ .p_class = P_GLOBAL,
+ .ptr = &Globals.iUsernameMapCacheTime,
+ .special = NULL,
+ .enum_list = NULL,
+ .flags = FLAG_ADVANCED,
+ },
+ {
.label = "logon script",
.type = P_STRING,
.p_class = P_GLOBAL,
@@ -5494,6 +5504,7 @@ FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
+FN_GLOBAL_INTEGER(lp_username_map_cache_time, &Globals.iUsernameMapCacheTime)
FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
diff --git a/source3/smbd/map_username.c b/source3/smbd/map_username.c
index 8c8eb2ed9d..dc5d48efaa 100644
--- a/source3/smbd/map_username.c
+++ b/source3/smbd/map_username.c
@@ -76,6 +76,48 @@ static char *skip_space(char *s)
return s;
}
+static bool fetch_map_from_gencache(fstring user)
+{
+ char *key, *value;
+ bool found;
+
+ if (lp_username_map_cache_time() == 0) {
+ return false;
+ }
+
+ key = talloc_asprintf_strupper_m(talloc_tos(), "USERNAME_MAP/%s",
+ user);
+ if (key == NULL) {
+ return false;
+ }
+ found = gencache_get(key, &value, NULL);
+ TALLOC_FREE(key);
+ if (!found) {
+ return false;
+ }
+ fstrcpy(user, value);
+ SAFE_FREE(value);
+ return true;
+}
+
+static void store_map_in_gencache(const char *from, const char *to)
+{
+ char *key;
+ int cache_time = lp_username_map_cache_time();
+
+ if (cache_time == 0) {
+ return;
+ }
+
+ key = talloc_asprintf_strupper_m(talloc_tos(), "USERNAME_MAP/%s",
+ from);
+ if (key == NULL) {
+ return;
+ }
+ gencache_set(key, to, cache_time + time(NULL));
+ TALLOC_FREE(key);
+}
+
bool map_username(struct smbd_server_connection *sconn, fstring user)
{
XFILE *f;
@@ -97,6 +139,10 @@ bool map_username(struct smbd_server_connection *sconn, fstring user)
return true;
}
+ if (fetch_map_from_gencache(user)) {
+ return true;
+ }
+
/* first try the username map script */
if ( *cmd ) {
@@ -134,6 +180,7 @@ bool map_username(struct smbd_server_connection *sconn, fstring user)
if (numlines && qlines) {
DEBUG(3,("Mapped user %s to %s\n", user, qlines[0] ));
set_last_from_to(user, qlines[0]);
+ store_map_in_gencache(user, qlines[0]);
fstrcpy( user, qlines[0] );
}
@@ -197,6 +244,7 @@ bool map_username(struct smbd_server_connection *sconn, fstring user)
mapped_user = True;
set_last_from_to(user, unixname);
+ store_map_in_gencache(user, unixname);
fstrcpy( user, unixname );
if ( return_if_mapped ) {
@@ -217,6 +265,7 @@ bool map_username(struct smbd_server_connection *sconn, fstring user)
*/
set_last_from_to(user, user);
+ store_map_in_gencache(user, user);
return mapped_user;
}