/*The following definitions come from passdb/smbpasschange.c */
-BOOL local_password_change(char *user_name, BOOL trust_account, BOOL add_user,
- BOOL enable_user, BOOL disable_user, BOOL set_no_password,
- char *new_passwd,
- char *err_str, size_t err_str_len,
- char *msg_str, size_t msg_str_len);
+BOOL local_password_change(char *user_name,
+ BOOL add_user,
+ uint16 acb_info, uint16 acb_mask,
+ char *new_passwd,
+ char *err_str, size_t err_str_len,
+ char *msg_str, size_t msg_str_len);
/*The following definitions come from passdb/smbpassfile.c */
{
int i;
for (i=0;i<len;i++)
- DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
+ {
+ DEBUGADD(level,("%c", isprint(buf[i])?buf[i]:'.'));
+ }
}
-void dump_data(int level,char *buf1,int len)
+void dump_data(int level,char *buf1, int len)
{
- unsigned char *buf = (unsigned char *)buf1;
- int i=0;
- if (len<=0) return;
+ unsigned char *buf = (unsigned char *)buf1;
+ int i=0;
+ if (len<=0) return;
- DEBUG(level,("[%03X] ",i));
- for (i=0;i<len;) {
- DEBUG(level,("%02X ",(int)buf[i]));
- i++;
- if (i%8 == 0) DEBUG(level,(" "));
- if (i%16 == 0) {
- print_asc(level,&buf[i-16],8); DEBUG(level,(" "));
- print_asc(level,&buf[i-8],8); DEBUG(level,("\n"));
- if (i<len) DEBUG(level,("[%03X] ",i));
- }
- }
- if (i%16) {
- int n;
-
- n = 16 - (i%16);
- DEBUG(level,(" "));
- if (n>8) DEBUG(level,(" "));
- while (n--) DEBUG(level,(" "));
-
- n = MIN(8,i%16);
- print_asc(level,&buf[i-(i%16)],n); DEBUG(level,(" "));
- n = (i%16) - n;
- if (n>0) print_asc(level,&buf[i-n],n);
- DEBUG(level,("\n"));
- }
+ DEBUG(level,("[%03X] ",i));
+ for (i=0;i<len;)
+ {
+ DEBUGADD(level,("%02X ",(int)buf[i]));
+ i++;
+ if (i%8 == 0) DEBUGADD(level,(" "));
+ if (i%16 == 0)
+ {
+ print_asc(level,&buf[i-16],8); DEBUGADD(level,(" "));
+ print_asc(level,&buf[i-8],8); DEBUGADD(level,("\n"));
+ if (i<len) DEBUGADD(level,("[%03X] ",i));
+ }
+ }
+
+ if (i%16 != 0) /* finish off a non-16-char-length row */
+ {
+ int n;
+
+ n = 16 - (i%16);
+ DEBUGADD(level,(" "));
+ if (n>8) DEBUGADD(level,(" "));
+ while (n--) DEBUGADD(level,(" "));
+
+ n = MIN(8,i%16);
+ print_asc(level,&buf[i-(i%16)],n); DEBUGADD(level,(" "));
+ n = (i%16) - n;
+ if (n>0) print_asc(level,&buf[i-n],n);
+ DEBUGADD(level,("\n"));
+ }
}
char *tab_depth(int depth)
*buf = '\0';
}
-/***************************************************************************
-Dumps out the browse packet data.
-**************************************************************************/
-
-static void debug_browse_data(char *outbuf, int len)
-{
- int i,j;
-
- DEBUG( 4, ( "debug_browse_data():\n" ) );
- for (i = 0; i < len; i+= 16)
- {
- DEBUGADD( 4, ( "%3x char ", i ) );
-
- for (j = 0; j < 16; j++)
- {
- unsigned char x = outbuf[i+j];
- if (x < 32 || x > 127)
- x = '.';
-
- if (i+j >= len)
- break;
- DEBUGADD( 4, ( "%c", x ) );
- }
-
- DEBUGADD( 4, ( "%*s hex", 16-j, "" ) );
-
- for (j = 0; j < 16; j++)
- {
- if (i+j >= len)
- break;
- DEBUGADD( 4, ( " %02x", (unsigned char)outbuf[i+j] ) );
- }
-
- DEBUGADD( 4, ("\n") );
- }
-}
-
/***************************************************************************
Generates the unique transaction identifier
**************************************************************************/
{
case ANN_HostAnnouncement:
{
- debug_browse_data(buf, len);
process_host_announce(subrec, p, buf+1);
break;
}
case ANN_DomainAnnouncement:
{
- debug_browse_data(buf, len);
process_workgroup_announce(subrec, p, buf+1);
break;
}
case ANN_LocalMasterAnnouncement:
{
- debug_browse_data(buf, len);
process_local_master_announce(subrec, p, buf+1);
break;
}
case ANN_AnnouncementRequest:
{
- debug_browse_data(buf, len);
process_announce_request(subrec, p, buf+1);
break;
}
case ANN_Election:
{
- debug_browse_data(buf, len);
process_election(subrec, p, buf+1);
break;
}
case ANN_GetBackupListReq:
{
- debug_browse_data(buf, len);
/* This is one occasion where we change a subnet that is
given to us. If the packet was sent to WORKGROUP<1b> instead
}
case ANN_GetBackupListResp:
{
- debug_browse_data(buf, len);
/* We never send ANN_GetBackupListReq so we
should never get these. */
DEBUG(0,("process_browse_packet: Discarding GetBackupListResponse \
}
case ANN_ResetBrowserState:
{
- debug_browse_data(buf, len);
process_reset_browser(subrec, p, buf+1);
break;
}
on the unicast subnet. */
subrec = unicast_subnet;
- debug_browse_data(buf, len);
process_master_browser_announce(subrec, p, buf+1);
break;
}
/*
* We don't currently implement this. Log it just in case.
*/
- debug_browse_data(buf, len);
DEBUG(10,("process_browse_packet: On subnet %s ignoring browse packet \
command ANN_BecomeBackup from %s IP %s to %s\n",
subrec->subnet_name, nmb_namestr(&dgram->source_name),
}
default:
{
- debug_browse_data(buf, len);
DEBUG(0,("process_browse_packet: On subnet %s ignoring browse packet \
command code %d from %s IP %s to %s\n",
subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
{
case ANN_HostAnnouncement:
{
- debug_browse_data(buf, len);
+ dump_data(4, buf, len);
process_lm_host_announce(subrec, p, buf+1);
break;
}
nmb_namestr(&dgram->source_name),nmb_namestr(&dgram->dest_name),
inet_ntoa(p->ip), smb_buf(buf),CVAL(buf2,0),len));
-
if (len <= 0)
return;
+ dump_data(100, buf2, len);
+
/* Datagram packet received for the browser mailslot */
if (strequal(smb_buf(buf),BROWSE_MAILSLOT))
{
nmb_namestr(&dgram->source_name), inet_ntoa(src_ip)));
DEBUG(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), inet_ntoa(dest_ip)));
- debug_browse_data(buf, len);
+ dump_data(4, buf, len);
if(loopback_this_packet)
{
/* Skip the ':' */
p++;
- if (*p == '*' || *p == 'X')
- {
- /* Password deliberately invalid - end here. */
- DEBUG(10, ("getsmbfilepwent: entry invalidated for unix user %s\n", unix_name));
- pw_buf.smb_nt_passwd = NULL;
- pw_buf.smb_passwd = NULL;
- pw_buf.acct_ctrl |= ACB_DISABLED;
- return &pw_buf;
- }
-
if (linebuf_len < (PTR_DIFF(p, linebuf) + 33))
{
DEBUG(0, ("getsmbfilepwent: malformed password entry (passwd too short)\n"));
}
}
+ if (*p == '*' || *p == 'X')
+ {
+ /* Password deliberately invalid - end here. */
+ DEBUG(10, ("getsmbfilepwent: entry invalidated for unix user %s\n", unix_name));
+ pw_buf.smb_nt_passwd = NULL;
+ pw_buf.smb_passwd = NULL;
+ pw_buf.acct_ctrl |= ACB_DISABLED;
+ }
+
+ DEBUG(6,("unixuser:%s uid:%d acb:%x\n",
+ pw_buf.unix_name, pw_buf.unix_uid, pw_buf.acct_ctrl));
+
return &pw_buf;
}
#ifdef DEBUG_PASSWORD
DEBUG(100,("mod_smbfilepwd_entry: password entries\n"));
- dump_data(100, pwd->smb_passwd, 16);
- dump_data(100, pwd->smb_nt_passwd, 16);
+ if (pwd->smb_passwd != NULL)
+ {
+ dump_data(100, pwd->smb_passwd, 16);
+ }
+ if (pwd->smb_nt_passwd != NULL)
+ {
+ dump_data(100, pwd->smb_nt_passwd, 16);
+ }
#endif
if (!*pfile) {
DEBUG(0, ("No SMB password file set\n"));
/*************************************************************
add a new user to the local smbpasswd file
*************************************************************/
-static BOOL add_new_user(char *user_name, uid_t uid, BOOL trust_account,
- BOOL disable_user, BOOL set_no_password,
- uchar *new_p16, uchar *new_nt_p16)
+static BOOL add_new_user(char *user_name, uid_t uid,
+ uint16 acb_info,
+ uchar *new_p16, uchar *new_nt_p16)
{
struct smb_passwd new_smb_pwent;
new_smb_pwent.nt_name = user_name;
new_smb_pwent.smb_passwd = NULL;
new_smb_pwent.smb_nt_passwd = NULL;
- new_smb_pwent.acct_ctrl = (trust_account ? ACB_WSTRUST : ACB_NORMAL);
+ new_smb_pwent.acct_ctrl = acb_info;
- if(disable_user) {
- new_smb_pwent.acct_ctrl |= ACB_DISABLED;
- } else if (set_no_password) {
- new_smb_pwent.acct_ctrl |= ACB_PWNOTREQ;
- } else {
+ if (IS_BITS_CLR_ALL(acb_info, ACB_DISABLED | ACB_PWNOTREQ))
+ {
new_smb_pwent.smb_passwd = new_p16;
new_smb_pwent.smb_nt_passwd = new_nt_p16;
}
/*************************************************************
-change a password entry in the local smbpasswd file
+change a password entry in the local smbpasswd file.
+
+when modifying an account, set acb_mask to those bits that
+require changing (to zero or one) and set acb_info to the
+value required in those bits. all bits NOT set in acb_mask
+will NOT be modified.
+
+when _adding_ an account, acb_mask must be set to 0xFFFF and
+it is ignored, btw :-)
+
*************************************************************/
-BOOL local_password_change(char *user_name, BOOL trust_account, BOOL add_user,
- BOOL enable_user, BOOL disable_user, BOOL set_no_password,
- char *new_passwd,
- char *err_str, size_t err_str_len,
- char *msg_str, size_t msg_str_len)
+BOOL local_password_change(char *user_name,
+ BOOL add_user,
+ uint16 acb_info, uint16 acb_mask,
+ char *new_passwd,
+ char *err_str, size_t err_str_len,
+ char *msg_str, size_t msg_str_len)
{
struct passwd *pwd;
struct smb_passwd *smb_pwent;
+ struct smb_passwd new_pwent;
uchar new_p16[16];
uchar new_nt_p16[16];
fstring unix_name;
pwd = getpwnam(user_name);
/*
- * Check for a machine account.
+ * Check for a trust account.
*/
+ if ((acb_info & acb_mask) != acb_info)
+ {
+ slprintf(err_str, err_str_len - 1, "programmer error: acb_info (%x) requests bits to be set outside of acb_mask (%x) range\n", acb_info, acb_mask);
+ }
+
if (pwd == NULL)
{
- if (trust_account)
+ if (!IS_BITS_SET_ALL(acb_info, ACB_NORMAL))
{
slprintf(err_str, err_str_len - 1, "User %s does not \
exist in system password file (usually /etc/passwd). \
-Cannot add machine account without a valid system user.\n", user_name);
+Cannot add trust account without a valid system user.\n", user_name);
}
else
{
/* Get the smb passwd entry for this user */
smb_pwent = getsmbpwnam(user_name);
- if (smb_pwent == NULL) {
- if(add_user == False) {
+ if (smb_pwent == NULL)
+ {
+ if (!add_user)
+ {
slprintf(err_str, err_str_len-1,
"Failed to find entry for user %s.\n", unix_name);
return False;
}
- if (add_new_user(user_name, unix_uid, trust_account, disable_user,
- set_no_password, new_p16, new_nt_p16)) {
+ if (add_new_user(user_name, unix_uid, acb_info,
+ new_p16, new_nt_p16))
+ {
slprintf(msg_str, msg_str_len-1, "Added user %s.\n", user_name);
return True;
- } else {
+ }
+ else
+ {
slprintf(err_str, err_str_len-1, "Failed to add entry for user %s.\n", user_name);
return False;
}
- } else {
+ }
+ else
+ {
/* the entry already existed */
add_user = False;
}
* and the valid last change time.
*/
- if(disable_user) {
- smb_pwent->acct_ctrl |= ACB_DISABLED;
- } else if (enable_user) {
- if(smb_pwent->smb_passwd == NULL) {
- smb_pwent->smb_passwd = new_p16;
- smb_pwent->smb_nt_passwd = new_nt_p16;
- }
- smb_pwent->acct_ctrl &= ~ACB_DISABLED;
- } else if (set_no_password) {
- smb_pwent->acct_ctrl |= ACB_PWNOTREQ;
- /* This is needed to preserve ACB_PWNOTREQ in mod_smbfilepwd_entry */
- smb_pwent->smb_passwd = NULL;
- smb_pwent->smb_nt_passwd = NULL;
- } else {
- smb_pwent->acct_ctrl &= ~ACB_PWNOTREQ;
- smb_pwent->smb_passwd = new_p16;
- smb_pwent->smb_nt_passwd = new_nt_p16;
+ memcpy(&new_pwent, smb_pwent, sizeof(new_pwent));
+ new_pwent.nt_name = user_name;
+ new_pwent.acct_ctrl &= ~acb_mask;
+ new_pwent.acct_ctrl |= (acb_info & acb_mask);
+ new_pwent.smb_passwd = NULL;
+ new_pwent.smb_nt_passwd = NULL;
+
+ if (IS_BITS_CLR_ALL(acb_info, ACB_DISABLED | ACB_PWNOTREQ))
+ {
+ new_pwent.smb_passwd = new_p16;
+ new_pwent.smb_nt_passwd = new_nt_p16;
}
- if(mod_smbpwd_entry(smb_pwent,True) == False) {
+ if (!mod_smbpwd_entry(&new_pwent, True))
+ {
slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n",
unix_name);
return False;
/*
- * Unix SMB/Netbios implementation. Version 1.9. smbpasswd module. Copyright
- * (C) Jeremy Allison 1995-1998
+ * Unix SMB/Netbios implementation. Version 1.9. smbpasswd module.
+ * Copyright (C) Jeremy Allison 1995-1999
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1999
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free
printf(" -d disable user\n");
printf(" -e enable user\n");
printf(" -n set no password\n");
- printf(" -m machine trust account\n");
+ printf(" -m workstation trust account\n");
+ printf(" -i inter-domain trust account\n");
}
exit(1);
}
change a password either locally or remotely
*************************************************************/
static BOOL password_change(const char *remote_machine, char *user_name,
- char *old_passwd, char *new_passwd,
- BOOL add_user, BOOL enable_user,
- BOOL disable_user, BOOL set_no_password,
- BOOL trust_account)
+ char *old_passwd, char *new_passwd,
+ BOOL add_user,
+ uint16 acb_info, uint16 acb_mask)
{
BOOL ret;
pstring err_str;
pstring msg_str;
- if (remote_machine != NULL) {
- if (add_user || enable_user || disable_user || set_no_password || trust_account) {
+ if (remote_machine != NULL)
+ {
+ if (add_user ||
+ IS_BITS_SET_SOME(acb_info, ACB_PWNOTREQ | ACB_WSTRUST | ACB_DOMTRUST | ACB_SVRTRUST) ||
+ (IS_BITS_SET_SOME(acb_mask, ACB_DISABLED) &&
+ IS_BITS_CLR_ALL(acb_info, ACB_DISABLED)))
+ {
/* these things can't be done remotely yet */
return False;
}
ret = remote_password_change(remote_machine, user_name,
- old_passwd, new_passwd, err_str, sizeof(err_str));
- if(*err_str)
+ old_passwd, new_passwd,
+ err_str, sizeof(err_str));
+ if (*err_str != 0)
+ {
fprintf(stderr, err_str);
+ }
return ret;
}
- ret = local_password_change(user_name, trust_account, add_user, enable_user,
- disable_user, set_no_password, new_passwd,
- err_str, sizeof(err_str), msg_str, sizeof(msg_str));
+ ret = local_password_change(user_name, add_user, acb_info, acb_mask,
+ new_passwd,
+ err_str, sizeof(err_str),
+ msg_str, sizeof(msg_str));
- if(*msg_str)
+ if (*msg_str != 0)
+ {
printf(msg_str);
- if(*err_str)
+ }
+ if (*err_str != 0)
+ {
fprintf(stderr, err_str);
+ }
return ret;
}
{
struct passwd *pwd;
int ch;
+ uint16 acb_info = 0;
+ uint16 acb_mask = 0;
BOOL joining_domain = False;
- BOOL trust_account = False;
+ BOOL wks_trust_account = False;
+ BOOL dom_trust_account = False;
BOOL add_user = False;
BOOL disable_user = False;
BOOL enable_user = False;
char *old_passwd = NULL;
char *remote_machine = NULL;
- while ((ch = getopt(argc, argv, "adehmnj:r:sR:D:U:")) != EOF) {
- switch(ch) {
- case 'a':
- add_user = True;
- break;
- case 'd':
- disable_user = True;
- new_passwd = "XXXXXX";
- break;
- case 'e':
- enable_user = True;
- break;
- case 'D':
- DEBUGLEVEL = atoi(optarg);
- break;
- case 'n':
- set_no_password = True;
- new_passwd = "NO PASSWORD";
- case 'r':
- remote_machine = optarg;
- break;
- case 's':
- set_line_buffering(stdin);
- set_line_buffering(stdout);
- set_line_buffering(stderr);
- stdin_passwd_get = True;
- break;
- case 'R':
- lp_set_name_resolve_order(optarg);
- break;
- case 'm':
- trust_account = True;
- break;
- case 'j':
- new_domain = optarg;
- strupper(new_domain);
- joining_domain = True;
- break;
- case 'U':
- user_name = optarg;
- break;
- default:
- usage();
+ while ((ch = getopt(argc, argv, "adehimnj:r:sR:D:U:")) != EOF)
+ {
+ switch(ch)
+ {
+ case 'a':
+ {
+ add_user = True;
+ break;
+ }
+ case 'd':
+ {
+ disable_user = True;
+ new_passwd = "XXXXXX";
+ break;
+ }
+ case 'e':
+ {
+ enable_user = True;
+ break;
+ }
+ case 'D':
+ {
+ DEBUGLEVEL = atoi(optarg);
+ break;
+ }
+ case 'n':
+ {
+ set_no_password = True;
+ new_passwd = "NO PASSWORD";
+ }
+ case 'r':
+ {
+ remote_machine = optarg;
+ break;
+ }
+ case 's':
+ {
+ set_line_buffering(stdin);
+ set_line_buffering(stdout);
+ set_line_buffering(stderr);
+ stdin_passwd_get = True;
+ break;
+ }
+ case 'R':
+ {
+ lp_set_name_resolve_order(optarg);
+ break;
+ }
+ case 'i':
+ {
+ dom_trust_account = True;
+ break;
+ }
+ case 'm':
+ {
+ wks_trust_account = True;
+ break;
+ }
+ case 'j':
+ {
+ new_domain = optarg;
+ strupper(new_domain);
+ joining_domain = True;
+ break;
+ }
+ case 'U':
+ {
+ user_name = optarg;
+ break;
+ }
+ default:
+ {
+ usage();
+ }
}
}
argc -= optind;
argv += optind;
-
/*
* Ensure add_user and either remote machine or join domain are
* not both set.
*/
- if(add_user && ((remote_machine != NULL) || joining_domain)) {
+ if (add_user && ((remote_machine != NULL) || joining_domain))
+ {
usage();
}
- if(joining_domain) {
+ if (joining_domain)
+ {
if (argc != 0) usage();
return join_domain(new_domain, remote_machine);
}
exit(1);
}
- if (trust_account) {
+ if (wks_trust_account || dom_trust_account)
+ {
/* add the $ automatically */
static fstring buf;
old_passwd = get_pass("Old SMB password:",stdin_passwd_get);
}
- if (!new_passwd) {
+ if (!new_passwd)
+ {
/*
* If we are trying to enable a user, first we need to find out
* smbpasswd file) then we need to prompt for a new password.
*/
- if(enable_user) {
+ if (enable_user)
+ {
struct smb_passwd *smb_pass = getsmbpwnam(user_name);
- if((smb_pass != NULL) && (smb_pass->smb_passwd != NULL)) {
+ if((smb_pass != NULL) && (smb_pass->smb_passwd != NULL))
+ {
new_passwd = "XXXX"; /* Don't care. */
}
}
if(!new_passwd)
+ {
new_passwd = prompt_for_new_password(stdin_passwd_get);
+ }
}
+ if (enable_user)
+ {
+ acb_mask |= ACB_DISABLED;
+ acb_info &= ~ACB_DISABLED;
+ }
+
+ if (disable_user)
+ {
+ acb_mask |= ACB_DISABLED;
+ acb_info |= ACB_DISABLED;
+ }
+
+ if (set_no_password)
+ {
+ acb_mask |= ACB_PWNOTREQ;
+ acb_info |= ACB_PWNOTREQ;
+ }
+
+ if (wks_trust_account)
+ {
+ acb_mask |= ACB_WSTRUST;
+ acb_info |= ACB_WSTRUST;
+ }
+ else if (dom_trust_account)
+ {
+ acb_mask |= ACB_DOMTRUST;
+ acb_info |= ACB_DOMTRUST;
+ }
+ else
+ {
+ acb_mask |= ACB_NORMAL;
+ acb_info |= ACB_NORMAL;
+ }
+
if (!password_change(remote_machine, user_name, old_passwd, new_passwd,
- add_user, enable_user, disable_user, set_no_password,
- trust_account)) {
+ add_user, acb_info, acb_mask))
+ {
fprintf(stderr,"Failed to change password entry for %s\n", user_name);
return 1;
}
- if(disable_user) {
+ if (disable_user)
+ {
printf("User %s disabled.\n", user_name);
- } else if(enable_user) {
+ }
+ if (enable_user)
+ {
printf("User %s enabled.\n", user_name);
- } else if (set_no_password) {
+ }
+ if (set_no_password)
+ {
printf("User %s - set to no password.\n", user_name);
- } else {
+ }
+ if (!disable_user && !enable_user && !set_no_password)
+ {
printf("Password changed for user %s\n", user_name);
}
return 0;
char *user_name = NULL;
char *new_passwd = NULL;
- while ((ch = getopt(argc, argv, "hD:r:sU:")) != EOF) {
- switch(ch) {
+ while ((ch = getopt(argc, argv, "hD:r:sU:")) != EOF)
+ {
+ switch(ch)
+ {
case 'D':
DEBUGLEVEL = atoi(optarg);
break;
exit(0);
}
- if (!password_change(remote_machine, user_name, old_passwd, new_passwd,
- False, False, False, False, False)) {
+ if (!password_change(remote_machine, user_name,
+ old_passwd, new_passwd,
+ False, 0x0, 0x0))
+ {
fprintf(stderr,"Failed to change password for %s\n", user_name);
return 1;
}
BOOL add_user, BOOL enable_user, BOOL disable_user)
{
BOOL ret = False;
+ uint16 acb_info = 0;
+ uint16 acb_mask = 0;
pstring err_str;
pstring msg_str;
return False;
}
- ret = local_password_change(user_name, False, add_user, enable_user,
- disable_user, False, new_passwd, err_str, sizeof(err_str),
- msg_str, sizeof(msg_str));
+ if (enable_user)
+ {
+ acb_mask |= ACB_DISABLED;
+ acb_info &= ~ACB_DISABLED;
+ }
+
+ if (disable_user)
+ {
+ acb_mask |= ACB_DISABLED;
+ acb_info |= ACB_DISABLED;
+ }
+
+ ret = local_password_change(user_name, add_user,
+ acb_info, acb_mask,
+ new_passwd, err_str, sizeof(err_str),
+ msg_str, sizeof(msg_str));
if(*msg_str)
printf("%s\n<p>", msg_str);