|
|
@ -659,6 +659,10 @@ static void apply_options_full(struct ast_vm_user *retval, struct ast_variable *
|
|
|
|
while (tmp) {
|
|
|
|
while (tmp) {
|
|
|
|
if (!strcasecmp(tmp->name, "password") || !strcasecmp(tmp->name, "secret")) {
|
|
|
|
if (!strcasecmp(tmp->name, "password") || !strcasecmp(tmp->name, "secret")) {
|
|
|
|
ast_copy_string(retval->password, tmp->value, sizeof(retval->password));
|
|
|
|
ast_copy_string(retval->password, tmp->value, sizeof(retval->password));
|
|
|
|
|
|
|
|
} else if (!strcasecmp(tmp->name, "secret")) {
|
|
|
|
|
|
|
|
/* dont let secret override vmpassword */
|
|
|
|
|
|
|
|
if ((strlen(retval->password) == 0))
|
|
|
|
|
|
|
|
ast_copy_string(retval->password, tmp->value, sizeof(retval->password));
|
|
|
|
} else if (!strcasecmp(tmp->name, "uniqueid")) {
|
|
|
|
} else if (!strcasecmp(tmp->name, "uniqueid")) {
|
|
|
|
ast_copy_string(retval->uniqueid, tmp->value, sizeof(retval->uniqueid));
|
|
|
|
ast_copy_string(retval->uniqueid, tmp->value, sizeof(retval->uniqueid));
|
|
|
|
} else if (!strcasecmp(tmp->name, "pager")) {
|
|
|
|
} else if (!strcasecmp(tmp->name, "pager")) {
|
|
|
@ -753,134 +757,87 @@ static int reset_user_pw(const char *context, const char *mailbox, const char *n
|
|
|
|
|
|
|
|
|
|
|
|
static void vm_change_password(struct ast_vm_user *vmu, const char *newpassword)
|
|
|
|
static void vm_change_password(struct ast_vm_user *vmu, const char *newpassword)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
/* There's probably a better way of doing this. */
|
|
|
|
struct ast_config *cfg=NULL;
|
|
|
|
/* That's why I've put the password change in a separate function. */
|
|
|
|
struct ast_variable *var=NULL;
|
|
|
|
/* This could also be done with a database function */
|
|
|
|
struct ast_category *cat=NULL;
|
|
|
|
|
|
|
|
char *category=NULL, *value=NULL, *new=NULL;
|
|
|
|
FILE *configin;
|
|
|
|
const char *tmp=NULL;
|
|
|
|
FILE *configout;
|
|
|
|
int len;
|
|
|
|
int linenum=0;
|
|
|
|
|
|
|
|
char inbuf[256];
|
|
|
|
|
|
|
|
char orig[256];
|
|
|
|
|
|
|
|
char currcontext[256] = "";
|
|
|
|
|
|
|
|
char tmpin[PATH_MAX];
|
|
|
|
|
|
|
|
char tmpout[PATH_MAX];
|
|
|
|
|
|
|
|
struct stat statbuf;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!change_password_realtime(vmu, newpassword))
|
|
|
|
if (!change_password_realtime(vmu, newpassword))
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
snprintf(tmpin, sizeof(tmpin), "%s/voicemail.conf", ast_config_AST_CONFIG_DIR);
|
|
|
|
/* check voicemail.conf */
|
|
|
|
snprintf(tmpout, sizeof(tmpout), "%s/voicemail.conf.new", ast_config_AST_CONFIG_DIR);
|
|
|
|
if ((cfg = ast_config_load_with_comments(VOICEMAIL_CONFIG))) {
|
|
|
|
configin = fopen(tmpin,"r");
|
|
|
|
while ((category = ast_category_browse(cfg, category))) {
|
|
|
|
if (configin)
|
|
|
|
if (!strcasecmp(category, vmu->context)) {
|
|
|
|
configout = fopen(tmpout,"w+");
|
|
|
|
tmp = ast_variable_retrieve(cfg, category, vmu->mailbox);
|
|
|
|
else
|
|
|
|
if (!tmp) {
|
|
|
|
configout = NULL;
|
|
|
|
ast_log(LOG_WARNING, "We could not find the mailbox.\n");
|
|
|
|
if (!configin || !configout) {
|
|
|
|
break;
|
|
|
|
if (configin)
|
|
|
|
}
|
|
|
|
fclose(configin);
|
|
|
|
value = strstr(tmp,",");
|
|
|
|
else
|
|
|
|
if (!value) {
|
|
|
|
ast_log(LOG_WARNING, "Warning: Unable to open '%s' for reading: %s\n", tmpin, strerror(errno));
|
|
|
|
ast_log(LOG_WARNING, "variable has bad format.\n");
|
|
|
|
if (configout)
|
|
|
|
break;
|
|
|
|
fclose(configout);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
len = (strlen(value) + strlen(newpassword));
|
|
|
|
ast_log(LOG_WARNING, "Warning: Unable to open '%s' for writing: %s\n", tmpout, strerror(errno));
|
|
|
|
|
|
|
|
return;
|
|
|
|
if (!(new = ast_calloc(1,len))) {
|
|
|
|
}
|
|
|
|
ast_log(LOG_WARNING, "Memory Allocation Failed.\n");
|
|
|
|
|
|
|
|
break;
|
|
|
|
while (!feof(configin)) {
|
|
|
|
}
|
|
|
|
char *user = NULL, *pass = NULL, *rest = NULL, *comment = NULL, *tmpctx = NULL, *tmpctxend = NULL;
|
|
|
|
sprintf(new,"%s%s", newpassword, value);
|
|
|
|
|
|
|
|
|
|
|
|
/* Read in the line */
|
|
|
|
if (!(cat = ast_category_get(cfg, category))) {
|
|
|
|
if (fgets(inbuf, sizeof(inbuf), configin) == NULL)
|
|
|
|
ast_log(LOG_WARNING, "Failed to get category structure.\n");
|
|
|
|
continue;
|
|
|
|
break;
|
|
|
|
linenum++;
|
|
|
|
}
|
|
|
|
|
|
|
|
ast_variable_update(cat, vmu->mailbox, new, NULL);
|
|
|
|
/* Make a backup of it */
|
|
|
|
|
|
|
|
ast_copy_string(orig, inbuf, sizeof(orig));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
Read the file line by line, split each line into a comment and command section
|
|
|
|
|
|
|
|
only parse the command portion of the line
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (inbuf[strlen(inbuf) - 1] == '\n')
|
|
|
|
|
|
|
|
inbuf[strlen(inbuf) - 1] = '\0';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((comment = strchr(inbuf, ';')))
|
|
|
|
|
|
|
|
*comment++ = '\0'; /* Now inbuf is terminated just before the comment */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (ast_strlen_zero(inbuf)) {
|
|
|
|
|
|
|
|
fprintf(configout, "%s", orig);
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Check for a context, first '[' to first ']' */
|
|
|
|
|
|
|
|
if ((tmpctx = strchr(inbuf, '['))) {
|
|
|
|
|
|
|
|
tmpctxend = strchr(tmpctx, ']');
|
|
|
|
|
|
|
|
if (tmpctxend) {
|
|
|
|
|
|
|
|
/* Valid context */
|
|
|
|
|
|
|
|
ast_copy_string(currcontext, tmpctx + 1, tmpctxend - tmpctx);
|
|
|
|
|
|
|
|
fprintf(configout, "%s", orig);
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* save the results */
|
|
|
|
/* This isn't a context line, check for MBX => PSWD... */
|
|
|
|
reset_user_pw(vmu->context, vmu->mailbox, newpassword);
|
|
|
|
user = inbuf;
|
|
|
|
ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
|
|
|
|
if ((pass = strchr(user, '='))) {
|
|
|
|
config_text_file_save(VOICEMAIL_CONFIG, cfg, "AppVoicemail");
|
|
|
|
/* We have a line in the form of aaaaa=aaaaaa */
|
|
|
|
if (new)
|
|
|
|
*pass++ = '\0';
|
|
|
|
free(new);
|
|
|
|
|
|
|
|
}
|
|
|
|
user = ast_strip(user);
|
|
|
|
category = NULL;
|
|
|
|
|
|
|
|
var = NULL;
|
|
|
|
if (*pass == '>')
|
|
|
|
/* check users.conf and update the password stored for the mailbox*/
|
|
|
|
*pass++ = '\0';
|
|
|
|
/* if no vmpassword entry exists create one. */
|
|
|
|
|
|
|
|
if ((cfg = ast_config_load_with_comments("users.conf"))) {
|
|
|
|
pass = ast_skip_blanks(pass);
|
|
|
|
ast_log(LOG_WARNING, "we are looking for %s\n", vmu->mailbox);
|
|
|
|
|
|
|
|
while ((category = ast_category_browse(cfg, category))) {
|
|
|
|
/*
|
|
|
|
ast_log(LOG_WARNING, "users.conf: %s\n", category);
|
|
|
|
Since no whitespace allowed in fields, or more correctly white space
|
|
|
|
if (!strcasecmp(category, vmu->mailbox)) {
|
|
|
|
inside the fields is there for a purpose, we can just terminate pass
|
|
|
|
if (!(tmp = ast_variable_retrieve(cfg, category, "vmpassword"))) {
|
|
|
|
at the comma or EOL whichever comes first.
|
|
|
|
ast_log(LOG_WARNING, "looks like we need to make vmpassword!\n");
|
|
|
|
*/
|
|
|
|
var = ast_variable_new("vmpassword", newpassword);
|
|
|
|
if ((rest = strchr(pass, ',')))
|
|
|
|
}
|
|
|
|
*rest++ = '\0';
|
|
|
|
if (!(new = ast_calloc(1,strlen(newpassword)))) {
|
|
|
|
} else {
|
|
|
|
ast_log(LOG_WARNING, "Memory Allocation Failed.\n");
|
|
|
|
user = NULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sprintf(new, "%s", newpassword);
|
|
|
|
/* Compare user, pass AND context */
|
|
|
|
if (!(cat = ast_category_get(cfg, category))) {
|
|
|
|
if (!ast_strlen_zero(user) && !strcmp(user, vmu->mailbox) &&
|
|
|
|
ast_log(LOG_WARNING, "failed to get category!\n");
|
|
|
|
!ast_strlen_zero(pass) && !strcmp(pass, vmu->password) &&
|
|
|
|
}
|
|
|
|
!strcasecmp(currcontext, vmu->context)) {
|
|
|
|
if (!var)
|
|
|
|
/* This is the line */
|
|
|
|
ast_variable_update(cat, "vmpassword", new, NULL);
|
|
|
|
if (rest) {
|
|
|
|
else
|
|
|
|
fprintf(configout, "%s => %s,%s", user, newpassword, rest);
|
|
|
|
ast_variable_append(cat, var);
|
|
|
|
} else {
|
|
|
|
|
|
|
|
fprintf(configout, "%s => %s", user, newpassword);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If there was a comment on the line print it out */
|
|
|
|
|
|
|
|
if (comment) {
|
|
|
|
|
|
|
|
fprintf(configout, ";%s\n", comment);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
fprintf(configout, "\n");
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
|
|
|
|
/* Put it back like it was */
|
|
|
|
|
|
|
|
fprintf(configout, "%s", orig);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* save the results and clean things up */
|
|
|
|
|
|
|
|
reset_user_pw(vmu->context, vmu->mailbox, newpassword);
|
|
|
|
|
|
|
|
ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
|
|
|
|
|
|
|
|
config_text_file_save("users.conf", cfg, "AppVoicemail");
|
|
|
|
|
|
|
|
if (new)
|
|
|
|
|
|
|
|
free(new);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fclose(configin);
|
|
|
|
|
|
|
|
fclose(configout);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
stat(tmpin, &statbuf);
|
|
|
|
|
|
|
|
chmod(tmpout, statbuf.st_mode);
|
|
|
|
|
|
|
|
chown(tmpout, statbuf.st_uid, statbuf.st_gid);
|
|
|
|
|
|
|
|
unlink(tmpin);
|
|
|
|
|
|
|
|
rename(tmpout, tmpin);
|
|
|
|
|
|
|
|
reset_user_pw(vmu->context, vmu->mailbox, newpassword);
|
|
|
|
|
|
|
|
ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void vm_change_password_shell(struct ast_vm_user *vmu, char *newpassword)
|
|
|
|
static void vm_change_password_shell(struct ast_vm_user *vmu, char *newpassword)
|
|
|
@ -6450,6 +6407,7 @@ static int vm_execmain(struct ast_channel *chan, void *data)
|
|
|
|
cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain);
|
|
|
|
cmd = forward_message(chan, context, &vms, vmu, vmfmts, 1, record_gain);
|
|
|
|
if (cmd == ERROR_LOCK_PATH) {
|
|
|
|
if (cmd == ERROR_LOCK_PATH) {
|
|
|
|
res = cmd;
|
|
|
|
res = cmd;
|
|
|
|
|
|
|
|
ast_log(LOG_WARNING, "forward_message failed to lock path.\n");
|
|
|
|
goto out;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
} else
|
|
|
|