Index: modules/lcr/lcr_mod.c
diff -Nau modules/lcr/lcr_mod.c.orig modules/lcr/lcr_mod.c
--- modules/lcr/lcr_mod.c.orig	2010-01-18 12:32:29.697648000 +0100
+++ modules/lcr/lcr_mod.c	2010-02-10 19:52:14.838272303 +0100
@@ -114,9 +114,18 @@
 
 #define PRIORITY_COL "priority"
 
+#define USER_COL "user"
+
+#define REALM_COL "realm"
+
+#define PASSWD_COL "passwd"
+
 #define MAX_NO_OF_GWS 32
 #define MAX_NO_OF_LCRS 256
 #define MAX_PREFIX_LEN 256
+#define MAX_USER_LEN 64
+#define MAX_REALM_LEN 64
+#define MAX_PASSWD_LEN 64
 #define MAX_TAG_LEN 16
 #define MAX_FROM_URI_LEN 256
 
@@ -141,6 +150,12 @@
     char tag[MAX_TAG_LEN + 1];
     unsigned short tag_len;
     unsigned int flags;
+    char user[MAX_USER_LEN];
+    unsigned short user_len;
+    char realm[MAX_REALM_LEN];
+    unsigned short realm_len;
+    char passwd[MAX_PASSWD_LEN];
+    unsigned short passwd_len;
 };
 
 struct lcr_info {
@@ -196,6 +211,9 @@
 static str prefix_col       = str_init(PREFIX_COL);
 static str from_uri_col     = str_init(FROM_URI_COL);
 static str priority_col     = str_init(PRIORITY_COL);
+static str user_col         = str_init(USER_COL);
+static str realm_col        = str_init(REALM_COL);
+static str passwd_col       = str_init(PASSWD_COL);
 
 /* timer */
 int fr_inv_timer      = DEF_FR_INV_TIMER;
@@ -208,6 +226,9 @@
 static char *contact_avp_param = NULL;
 static char *rpid_avp_param = NULL;
 static char *flags_avp_param = NULL;
+static char *user_avp_param = NULL;
+static char *realm_avp_param = NULL;
+static char *passwd_avp_param = NULL;
 
 /* prefix mode */
 int prefix_mode_param = DEF_PREFIX_MODE;
@@ -239,6 +260,12 @@
 static int_str rpid_avp;
 static int     flags_avp_type;
 static int_str flags_avp;
+static int     user_avp_type;
+static int_str user_avp;
+static int     realm_avp_type;
+static int_str realm_avp;
+static int     passwd_avp_type;
+static int_str passwd_avp;
 
 struct gw_info **gws;	/* Pointer to current gw table pointer */
 struct gw_info *gws_1;	/* Pointer to gw table 1 */
@@ -327,6 +354,12 @@
 	{"fr_inv_timer",             INT_PARAM, &fr_inv_timer },
 	{"fr_inv_timer_next",        INT_PARAM,	&fr_inv_timer_next },
 	{"prefix_mode",              INT_PARAM, &prefix_mode_param },
+	{"user_column",              STR_PARAM, &user_col.s },
+	{"realm_column",             STR_PARAM, &realm_col.s },
+	{"passwd_column",            STR_PARAM, &passwd_col.s },
+	{"auth_username_avp",        STR_PARAM, &user_avp_param },
+	{"auth_realm_avp",           STR_PARAM, &realm_avp_param },
+	{"auth_password_avp",        STR_PARAM, &passwd_avp_param },
 	{0, 0, 0}
 };
 
@@ -438,6 +471,9 @@
     prefix_col.len = strlen(prefix_col.s);
     from_uri_col.len = strlen(from_uri_col.s);
     priority_col.len = strlen(priority_col.s);
+    user_col.len = strlen(user_col.s);
+    realm_col.len = strlen(realm_col.s);
+    passwd_col.len = strlen(passwd_col.s);
 
     /* Bind database */
     if (lcr_db_bind(&db_url)) {
@@ -563,6 +599,60 @@
 	return -1;
     }
 
+	if (user_avp_param && *user_avp_param) {
+	s.s = user_avp_param; s.len = strlen(s.s);
+	if (pv_parse_spec(&s, &avp_spec)==0
+	    || avp_spec.type!=PVT_AVP) {
+	    LM_ERR("Malformed or non AVP definition <%s>\n", user_avp_param);
+	    return -1;
+	}
+	
+	if(pv_get_avp_name(0, &(avp_spec.pvp), &user_avp, &avp_flags)!=0) {
+	    LM_ERR("Invalid AVP definition <%s>\n", user_avp_param);
+	    return -1;
+	}
+	user_avp_type = avp_flags;
+    } else {
+	LM_ERR("AVP user_avp has not been defined\n");
+	return -1;
+    }
+
+	if (realm_avp_param && *realm_avp_param) {
+	s.s = realm_avp_param; s.len = strlen(s.s);
+	if (pv_parse_spec(&s, &avp_spec)==0
+	    || avp_spec.type!=PVT_AVP) {
+	    LM_ERR("Malformed or non AVP definition <%s>\n", realm_avp_param);
+	    return -1;
+	}
+	
+	if(pv_get_avp_name(0, &(avp_spec.pvp), &realm_avp, &avp_flags)!=0) {
+	    LM_ERR("Invalid AVP definition <%s>\n", realm_avp_param);
+	    return -1;
+	}
+	realm_avp_type = avp_flags;
+    } else {
+	LM_ERR("AVP realm_avp has not been defined\n");
+	return -1;
+    }
+
+	if (passwd_avp_param && *passwd_avp_param) {
+	s.s = passwd_avp_param; s.len = strlen(s.s);
+	if (pv_parse_spec(&s, &avp_spec)==0
+	    || avp_spec.type!=PVT_AVP) {
+	    LM_ERR("Malformed or non AVP definition <%s>\n", passwd_avp_param);
+	    return -1;
+	}
+	
+	if(pv_get_avp_name(0, &(avp_spec.pvp), &passwd_avp, &avp_flags)!=0) {
+	    LM_ERR("Invalid AVP definition <%s>\n", passwd_avp_param);
+	    return -1;
+	}
+	passwd_avp_type = avp_flags;
+    } else {
+	LM_ERR("AVP passwd_avp has not been defined\n");
+	return -1;
+    }
+
     /* Check table version */
 	db_con_t* dbh;
 	if (lcr_dbf.init==0){
@@ -801,16 +891,17 @@
 int reload_gws(void)
 {
     unsigned int i, port, strip, tag_len, prefix_len, from_uri_len,
-    grp_id, priority;
+    user_len, realm_len, passwd_len, grp_id, priority;
     struct in_addr ip_addr;
     unsigned int flags;
     uri_type scheme;
     uri_transport transport;
     db_con_t* dbh;
     char *tag, *prefix, *from_uri;
+    char *user, *realm, *passwd;
     db_res_t* res = NULL;
     db_row_t* row;
-    db_key_t gw_cols[8];
+    db_key_t gw_cols[11];
     db_key_t lcr_cols[4];
 
     gw_cols[0] = &ip_addr_col;
@@ -823,6 +914,9 @@
        in the two tables? (ge vw lcr) */
     gw_cols[6] = &grp_id_col;
     gw_cols[7] = &flags_col;
+    gw_cols[8] = &user_col;
+    gw_cols[9] = &realm_col;
+    gw_cols[10] = &passwd_col;
 
     lcr_cols[0] = &prefix_col;
     lcr_cols[1] = &from_uri_col;
@@ -846,7 +940,7 @@
 	return -1;
     }
 
-    if (lcr_dbf.query(dbh, NULL, 0, NULL, gw_cols, 0, 8, 0, &res) < 0) {
+    if (lcr_dbf.query(dbh, NULL, 0, NULL, gw_cols, 0, 11, 0, &res) < 0) {
 	    LM_ERR("Failed to query gw data\n");
 	    lcr_dbf.close(dbh);
 	    return -1;
@@ -938,6 +1032,45 @@
 	    lcr_dbf.close(dbh);
 	    return -1;
 	}
+	if (VAL_NULL(ROW_VALUES(row) + 8) == 1) {
+	    user_len = 0;
+	    user = (char *)0;
+	} else {
+	    user = (char *)VAL_STRING(ROW_VALUES(row) + 8);
+	    user_len = strlen(user);
+	    if (user_len > MAX_USER_LEN) {
+		LM_ERR("Too long gw user <%u>\n", user_len);
+		lcr_dbf.free_result(dbh, res);
+		lcr_dbf.close(dbh);
+		return -1;
+	    }
+	}
+	if (VAL_NULL(ROW_VALUES(row) + 9) == 1) {
+	    realm_len = 0;
+	    realm = (char *)0;
+	} else {
+	    realm = (char *)VAL_STRING(ROW_VALUES(row) + 9);
+	    realm_len = strlen(realm);
+	    if (realm_len > MAX_REALM_LEN) {
+		LM_ERR("Too long gw realm <%u>\n", realm_len);
+		lcr_dbf.free_result(dbh, res);
+		lcr_dbf.close(dbh);
+		return -1;
+	    }
+	}
+	if (VAL_NULL(ROW_VALUES(row) + 10) == 1) {
+	    passwd_len = 0;
+	    passwd = (char *)0;
+	} else {
+	    passwd = (char *)VAL_STRING(ROW_VALUES(row) + 10);
+	    passwd_len = strlen(passwd);
+	    if (passwd_len > MAX_PASSWD_LEN) {
+		LM_ERR("Too long gw passwd <%u>\n", passwd_len);
+		lcr_dbf.free_result(dbh, res);
+		lcr_dbf.close(dbh);
+		return -1;
+	    }
+	}
 	if (*gws == gws_1) {
 	    gws_2[i].ip_addr = (unsigned int)ip_addr.s_addr;
 	    gws_2[i].port = port;
@@ -949,6 +1082,15 @@
 	    gws_2[i].tag_len = tag_len;
 	    if (tag_len)
 		memcpy(&(gws_2[i].tag[0]), tag, tag_len);
+	    gws_2[i].user_len = user_len;
+	    if (user_len)
+	    memcpy(&(gws_2[i].user[0]), user, user_len);
+	    gws_2[i].realm_len = realm_len;
+	    if (realm_len)
+	    memcpy(&(gws_2[i].realm[0]), realm, realm_len);
+	    gws_2[i].passwd_len = passwd_len;
+	    if (passwd_len)
+	    memcpy(&(gws_2[i].passwd[0]), passwd, passwd_len);
 	} else {
 	    gws_1[i].ip_addr = (unsigned int)ip_addr.s_addr;
 	    gws_1[i].port = port;
@@ -960,6 +1102,15 @@
 	    gws_1[i].tag_len = tag_len;
 	    if (tag_len)
 		memcpy(&(gws_1[i].tag[0]), tag, tag_len);
+	    gws_1[i].user_len = user_len;
+	    if (user_len)
+	    memcpy(&(gws_1[i].user[0]), user, user_len);
+	    gws_1[i].realm_len = realm_len;
+	    if (realm_len)
+	    memcpy(&(gws_1[i].realm[0]), realm, realm_len);
+	    gws_1[i].passwd_len = passwd_len;
+	    if (passwd_len)
+	    memcpy(&(gws_1[i].passwd[0]), passwd, passwd_len);
 	}
     }
 
@@ -1141,6 +1292,21 @@
 	attr = add_mi_attr(node, MI_DUP_VALUE, "FLAGS", 5, p, len);
 	if(attr == NULL)
 	    return -1;
+
+	attr = add_mi_attr(node, MI_DUP_VALUE, "USER", 6,
+			   (*gws)[i].user, (*gws)[i].user_len );
+	if(attr == NULL)
+	    return -1;
+
+	attr = add_mi_attr(node, MI_DUP_VALUE, "REALM", 6,
+			   (*gws)[i].realm, (*gws)[i].realm_len );
+	if(attr == NULL)
+	    return -1;
+
+	attr = add_mi_attr(node, MI_DUP_VALUE, "PASSWD", 6,
+			   (*gws)[i].passwd, (*gws)[i].passwd_len );
+	if(attr == NULL)
+	    return -1;
     }
 
     for (i = 0; i < MAX_NO_OF_LCRS; i++) {
@@ -1184,6 +1350,9 @@
     char ruri[MAX_URI_SIZE];
     unsigned int i, j, k, index, addr, port, strip, gw_index,
 	duplicated_gw, flags, have_rpid_avp;
+    char *user;
+    char *realm;
+    char *passwd;
     uri_type scheme;
     uri_transport transport;
     struct ip_addr address;
@@ -1407,6 +1576,9 @@
 	transport = (*gws)[index].transport;
 	flags = (*gws)[index].flags;
 	strip = (*gws)[index].strip;
+	user = (*gws)[index].user;
+	realm = (*gws)[index].realm;
+	passwd = (*gws)[index].passwd;
 	if (strip > ruri_user.len) {
 	    LM_ERR("Strip count of gw is too large <%u>\n", strip);
 	    goto skip;
@@ -1476,6 +1648,25 @@
 	val.s = value;
 	add_avp(gw_uri_avp_type|AVP_VAL_STR, gw_uri_avp, val);
 	LM_DBG("Added gw_uri_avp <%.*s>\n", value.len, value.s);
+
+	value.s = user;
+	value.len = strlen(value.s);
+	val.s = value;
+	add_avp(user_avp_type|AVP_VAL_STR, user_avp, val);
+	LM_DBG("Added user_avp <%.*s>\n", value.len, value.s);
+
+	value.s = realm;
+	value.len = strlen(value.s);
+	val.s = value;
+	add_avp(realm_avp_type|AVP_VAL_STR, realm_avp, val);
+	LM_DBG("Added realm_avp <%.*s>\n", value.len, value.s);
+
+	value.s = passwd;
+	value.len = strlen(value.s);
+	val.s = value;
+	add_avp(passwd_avp_type|AVP_VAL_STR, passwd_avp, val);
+	LM_DBG("Added passwd_avp <%.*s>\n", value.len, value.s);
+
     skip:
 	continue;
     }
@@ -1558,7 +1749,8 @@
 static int next_gw(struct sip_msg* _m, char* _s1, char* _s2)
 {
     int_str gw_uri_val, ruri_user_val, val;
-    struct usr_avp *gu_avp, *ru_avp;
+    int_str user_val, realm_val, passwd_val;
+    struct usr_avp *gu_avp, *ru_avp, *usr_avp, *rlm_avp, *pwd_avp;
     int rval;
     str new_ruri;
     char *at, *at_char, *strip_char, *endptr;
@@ -1575,6 +1767,35 @@
     gw_uri_val.s.len = gw_uri_val.s.len - (at - gw_uri_val.s.s);
     gw_uri_val.s.s = at;
 
+	/* Save gateway AVPs for use in script */
+	usr_avp = search_first_avp(user_avp_type, user_avp, &user_val, 0);
+	rlm_avp = search_first_avp(realm_avp_type, realm_avp, &realm_val, 0);
+	pwd_avp = search_first_avp(passwd_avp_type, passwd_avp, &passwd_val, 0);
+	if (!usr_avp) {
+		LM_DBG("User AVP no set\n");
+		return -1;
+	}
+	else {
+		add_avp(user_avp_type|AVP_VAL_STR, user_avp, user_val);
+		LM_DBG("Added user_avp <%.*s>\n", user_val.s.len, user_val.s.s);
+	}
+	if (!rlm_avp) {
+		LM_DBG("Realm AVP no set\n");
+		return -1;
+	}
+	else {
+		add_avp(realm_avp_type|AVP_VAL_STR, realm_avp, realm_val);
+		LM_DBG("Added realm_avp <%.*s>\n", realm_val.s.len, realm_val.s.s);
+	}
+	if (!pwd_avp) {
+		LM_DBG("Passwd AVP no set\n");
+		return -1;
+	}
+	else {
+		add_avp(passwd_avp_type|AVP_VAL_STR, passwd_avp, passwd_val);
+		LM_DBG("Added passwd_avp <%.*s>\n", passwd_val.s.len, passwd_val.s.s);
+	}
+
 	/* Create new Request-URI taking URI user from ruri_user AVP
 	   and other parts of from gateway URI AVP. */
 	ru_avp = search_first_avp(ruri_user_avp_type, ruri_user_avp,
Index: scripts/db_berkeley/opensips/gw
diff -Nau scripts/db_berkeley/opensips/gw.orig scripts/db_berkeley/opensips/gw
--- scripts/db_berkeley/opensips/gw.orig	2010-01-18 12:31:09.312068000 +0100
+++ scripts/db_berkeley/opensips/gw	2010-02-10 19:57:18.467214268 +0100
@@ -1,5 +1,5 @@
 METADATA_COLUMNS
-id(int) gw_name(str) grp_id(int) ip_addr(str) port(int) uri_scheme(int) transport(int) strip(int) tag(str) flags(int)
+id(int) gw_name(str) grp_id(int) ip_addr(str) port(int) uri_scheme(int) transport(int) strip(int) tag(str) flags(int) user(str) realm(str) passwd(str)
 METADATA_KEY
 1 
 METADATA_READONLY
@@ -7,4 +7,4 @@
 METADATA_LOGFLAGS
 0
 METADATA_DEFAULTS
-NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NULL|0
+NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NULL|0|NULL|NULL|NULL
Index: scripts/dbtext/opensips/gw
diff -Nau scripts/dbtext/opensips/gw.orig scripts/dbtext/opensips/gw
--- scripts/dbtext/opensips/gw.orig	2010-01-18 12:31:01.221183000 +0100
+++ scripts/dbtext/opensips/gw	2010-02-10 19:57:19.099512686 +0100
@@ -1 +1 @@
-id(int,auto) gw_name(string) grp_id(int) ip_addr(string) port(int,null) uri_scheme(int,null) transport(int,null) strip(int,null) tag(string,null) flags(int) 
+id(int,auto) gw_name(string) grp_id(int) ip_addr(string) port(int,null) uri_scheme(int,null) transport(int,null) strip(int,null) tag(string,null) flags(int) user(string,null) realm(string,null) passwd(string,null)
Index: scripts/mysql/lcr-create.sql
diff -Nau scripts/mysql/lcr-create.sql.orig scripts/mysql/lcr-create.sql
--- scripts/mysql/lcr-create.sql.orig	2010-01-18 12:31:05.995635000 +0100
+++ scripts/mysql/lcr-create.sql	2010-02-10 20:00:24.123864285 +0100
@@ -10,6 +10,9 @@
     strip TINYINT UNSIGNED,
     tag CHAR(16) DEFAULT NULL,
     flags INT UNSIGNED DEFAULT 0 NOT NULL,
+    user CHAR(16) DEFAULT NULL,
+    realm CHAR(16) DEFAULT NULL,
+    passwd CHAR(16) DEFAULT NULL,
     CONSTRAINT gw_name_idx UNIQUE (gw_name)
 ) ENGINE=MyISAM;
 
Index: scripts/oracle/lcr-create.sql
diff -Nau scripts/oracle/lcr-create.sql.orig scripts/oracle/lcr-create.sql
--- scripts/oracle/lcr-create.sql.orig	2010-01-18 12:31:09.035730000 +0100
+++ scripts/oracle/lcr-create.sql	2010-02-10 20:00:23.643867960 +0100
@@ -10,6 +10,9 @@
     strip NUMBER(5),
     tag VARCHAR2(16) DEFAULT NULL,
     flags NUMBER(10) DEFAULT 0 NOT NULL,
+    user VARCHAR2(16) DEFAULT NULL,
+    realm VARCHAR2(16) DEFAULT NULL,
+    passwd VARCHAR2(16) DEFAULT NULL,
     CONSTRAINT gw_gw_name_idx  UNIQUE (gw_name)
 );
 
Index: scripts/postgres/lcr-create.sql
diff -Nau scripts/postgres/lcr-create.sql.orig scripts/postgres/lcr-create.sql
--- scripts/postgres/lcr-create.sql.orig	2010-01-18 12:31:09.151881000 +0100
+++ scripts/postgres/lcr-create.sql	2010-02-10 19:59:19.649196584 +0100
@@ -10,6 +10,9 @@
     strip SMALLINT,
     tag VARCHAR(16) DEFAULT NULL,
     flags INTEGER DEFAULT 0 NOT NULL,
+    user VARCHAR(16) DEFAULT NULL,
+    realm VARCHAR(16) DEFAULT NULL,
+    passwd VARCHAR(16) DEFAULT NULL,
     CONSTRAINT gw_gw_name_idx UNIQUE (gw_name)
 );
 
