1 #define MODULE_LOG_PREFIX "config"
4 #include "module-anticasc.h"
5 #include "oscam-array.h"
6 #include "oscam-client.h"
7 #include "oscam-conf.h"
8 #include "oscam-conf-chk.h"
9 #include "oscam-conf-mk.h"
10 #include "oscam-config.h"
11 #include "oscam-garbage.h"
12 #include "oscam-lock.h"
13 #include "oscam-string.h"
15 #define cs_user "oscam.user"
17 static void account_tosleep_fn(const char *token
, char *value
, void *setting
, FILE *f
)
19 int32_t *tosleep
= setting
;
22 *tosleep
= strToIntVal(value
, cfg
.tosleep
);
25 if(*tosleep
!= cfg
.tosleep
|| cfg
.http_full_cfg
)
26 { fprintf_conf(f
, token
, "%d\n", *tosleep
); }
29 static void account_c35_suppresscmd08_fn(const char *token
, char *value
, void *setting
, FILE *f
)
31 int8_t *c35_suppresscmd08
= setting
;
34 *c35_suppresscmd08
= (int8_t)strToIntVal(value
, cfg
.c35_suppresscmd08
);
37 if(*c35_suppresscmd08
!= cfg
.c35_suppresscmd08
|| cfg
.http_full_cfg
)
38 { fprintf_conf(f
, token
, "%d\n", *c35_suppresscmd08
); }
41 /*static void account_umaxidle_fn(const char *token, char *value, void *setting, FILE *f)
43 int32_t *umaxidle = setting;
46 *umaxidle = (int32_t)strToIntVal(value, cfg.umaxidle);
49 if(*umaxidle != cfg.umaxidle || cfg.http_full_cfg)
50 { fprintf_conf(f, token, "%u\n", *umaxidle); }
54 static void account_ncd_keepalive_fn(const char *token
, char *value
, void *setting
, FILE *f
)
56 int8_t *ncd_keepalive
= setting
;
59 def_value
= cfg
.ncd_keepalive
;
63 *ncd_keepalive
= (int8_t)strToIntVal(value
, def_value
);
66 if(*ncd_keepalive
!= def_value
|| cfg
.http_full_cfg
)
67 { fprintf_conf(f
, token
, "%d\n", *ncd_keepalive
); }
70 static void account_allowedprotocols_fn(const char *token
, char *value
, void *setting
, FILE *f
)
72 struct s_auth
*account
= setting
;
75 account
->allowedprotocols
= 0;
79 char *ptr
, *saveptr1
= NULL
;
80 for(i
= 0, ptr
= strtok_r(value
, ",", &saveptr1
); ptr
; ptr
= strtok_r(NULL
, ",", &saveptr1
), i
++)
82 if(streq(ptr
, "camd33")) { account
->allowedprotocols
|= LIS_CAMD33TCP
; }
83 else if(streq(ptr
, "camd35")) { account
->allowedprotocols
|= LIS_CAMD35UDP
; }
84 else if(streq(ptr
, "cs357x")) { account
->allowedprotocols
|= LIS_CAMD35UDP
; }
85 else if(streq(ptr
, "cs378x")) { account
->allowedprotocols
|= LIS_CAMD35TCP
; }
86 else if(streq(ptr
, "newcamd")) { account
->allowedprotocols
|= LIS_NEWCAMD
; }
87 else if(streq(ptr
, "cccam")) { account
->allowedprotocols
|= LIS_CCCAM
; }
88 else if(streq(ptr
, "csp")) { account
->allowedprotocols
|= LIS_CSPUDP
; }
89 else if(streq(ptr
, "gbox")) { account
->allowedprotocols
|= LIS_GBOX
; }
90 else if(streq(ptr
, "radegast")) { account
->allowedprotocols
|= LIS_RADEGAST
; }
91 else if(streq(ptr
, "scam")) { account
->allowedprotocols
|= LIS_SCAM
; }
92 // these have no listener ports so it doesn't make sense
93 else if(streq(ptr
, "dvbapi")) { account
->allowedprotocols
|= LIS_DVBAPI
; }
94 else if(streq(ptr
, "constcw")) { account
->allowedprotocols
|= LIS_CONSTCW
; }
95 else if(streq(ptr
, "serial")) { account
->allowedprotocols
|= LIS_SERIAL
; }
100 if(account
->allowedprotocols
|| cfg
.http_full_cfg
)
102 value
= mk_t_allowedprotocols(account
);
103 fprintf_conf(f
, token
, "%s\n", value
);
108 static void account_au_fn(const char *token
, char *value
, void *setting
, FILE *f
)
110 struct s_auth
*account
= setting
;
113 // set default values for usage during runtime from Webif
115 if(!account
->aureader_list
)
116 { account
->aureader_list
= ll_create("aureader_list"); }
117 if(streq(value
, "1"))
118 { account
->autoau
= 1; }
119 ll_clear(account
->aureader_list
);
120 LL_ITER itr
= ll_iter_create(configured_readers
);
121 struct s_reader
*rdr
;
122 char *pch
, *saveptr1
= NULL
;
123 for(pch
= strtok_r(value
, ",", &saveptr1
); pch
!= NULL
; pch
= strtok_r(NULL
, ",", &saveptr1
))
126 while((rdr
= ll_iter_next(&itr
)))
128 if(streq(rdr
->label
, pch
) || account
->autoau
)
130 ll_append(account
->aureader_list
, rdr
);
136 if(account
->autoau
== 1)
138 fprintf_conf(f
, token
, "%d\n", account
->autoau
);
140 else if(account
->aureader_list
)
142 value
= mk_t_aureader(account
);
143 if(strlen(value
) > 0)
144 { fprintf_conf(f
, token
, "%s\n", value
); }
147 else if(cfg
.http_full_cfg
)
149 fprintf_conf(f
, token
, "%s\n", "");
153 static void account_expdate_fn(const char *token
, char *value
, void *setting
, FILE *f
)
155 struct s_auth
*account
= setting
;
160 account
->expirationdate
= (time_t)NULL
;
165 char *ptr1
, *saveptr1
= NULL
;
166 memset(&cstime
, 0, sizeof(cstime
));
167 for(i
= 0, ptr1
= strtok_r(value
, "-/", &saveptr1
); i
< 3 && ptr1
; ptr1
= strtok_r(NULL
, "-/", &saveptr1
), i
++)
172 cstime
.tm_year
= atoi(ptr1
) - 1900;
175 cstime
.tm_mon
= atoi(ptr1
) - 1;
178 cstime
.tm_mday
= atoi(ptr1
);
185 cstime
.tm_isdst
= -1;
186 account
->expirationdate
= mktime(&cstime
);
189 if(account
->expirationdate
|| cfg
.http_full_cfg
)
193 localtime_r(&account
->expirationdate
, &timeinfo
);
194 strftime(buf
, 16, "%Y-%m-%d", &timeinfo
);
195 fprintf_conf(f
, token
, "%s\n", streq(buf
, "1970-01-01") ? "" : buf
);
199 static void account_allowedtimeframe_fn(const char *token
, char *value
, void *setting
, FILE *f
)
201 struct s_auth
*account
= setting
;
202 int32_t i
, j
, t
, startt
, endt
;
208 char *ptr1
, *ptr2
, *ptr3
, *saveptr1
= NULL
, *saveptr2
= NULL
;
212 //First empty allowedtimeframe array very important otherwise new config won't be properly set
213 for(i
= 0; i
< SIZE_SHORTDAY
; i
++)
215 for(j
= 0; j
< 24; j
++)
217 account
->allowedtimeframe
[i
][j
][0] = 0;
218 account
->allowedtimeframe
[i
][j
][1] = 0;
221 account
->allowedtimeframe_set
=0;
224 for(i
= 0, ptr1
= strtok_r(value
, ";", &saveptr1
); (ptr1
); ptr1
= strtok_r(NULL
, ";", &saveptr1
), i
++)
226 if((ptr2
= strchr(trim(ptr1
), '@')))
228 *ptr2
++ = '\0'; // clean up @ symbol
230 dest
= strstr(weekdstr
,ptr1
);
231 day_idx
= (dest
- weekdstr
) / 3;
233 for(j
= 0, ptr3
= strtok_r(ptr2
, ",", &saveptr2
); (ptr3
); ptr3
= strtok_r(NULL
, ",", &saveptr2
), j
++)
235 if((sscanf(ptr3
, "%2d:%2d-%2d:%2d", &allowed
[0], &allowed
[1], &allowed
[2], &allowed
[3]) == 4) && (day_idx
< SIZE_SHORTDAY
))
237 startt
= allowed
[0] * 60 + allowed
[1];
238 endt
= allowed
[2] * 60 + allowed
[3];
240 if(startt
== endt
) { endt
++; } // end time cannot be the same as the star time
241 if((startt
< 0) || (startt
> 1439)) { startt
= 0; } // could not start later than 23H59, avoid overflow
242 if((endt
< 0) || (endt
> 1440)) { endt
= 1440; } // could not be higher than 24H00, avoid overflow
244 account
->allowedtimeframe_set
= 1;
248 for(t
= startt
; t
< 1440; t
++)
250 tempo
= (1 << (t
% 30));
251 account
->allowedtimeframe
[day_idx
][t
/ 60][(t
/ 30) % 2] = account
->allowedtimeframe
[day_idx
][t
/ 60][(t
/ 30) % 2] | tempo
;
256 for(t
= startt
; t
< endt
; t
++)
258 tempo
= (1 << (t
% 30));
259 account
->allowedtimeframe
[day_idx
][t
/ 60][((t
/ 30) % 2)] = account
->allowedtimeframe
[day_idx
][t
/ 60][(t
/ 30) % 2] | tempo
;
264 fprintf(stderr
, "WARNING: Value '%s' is not valid for allowedtimeframe (DAY@HH:MM-HH:MM)\n", value
);
268 else // No day specified so whole week (ALL)
270 if(sscanf(ptr1
, "%2d:%2d-%2d:%2d", &allowed
[0], &allowed
[1], &allowed
[2], &allowed
[3]) == 4)
272 startt
= allowed
[0] * 60 + allowed
[1];
273 endt
= allowed
[2] * 60 + allowed
[3];
275 if(startt
== endt
) { endt
++; } // end time cannot be the same as the star time
276 if((startt
<0) || (startt
> 1439)) { startt
= 0; } // could not start later than 23H59, avoid overflow
277 if((endt
<0) || (endt
> 1440)) { endt
= 1440; } // could not be higher than 24H00, avoid overflow
279 account
->allowedtimeframe_set
= 1;
280 dest
= strstr(weekdstr
,"ALL");
281 day_idx
= (dest
- weekdstr
) / 3;
285 for(t
= startt
; t
< 1440; t
++)
287 tempo
= (1 << (t
% 30));
288 account
->allowedtimeframe
[day_idx
][t
/ 60][(t
/ 30) % 2] = account
->allowedtimeframe
[7][t
/ 60][(t
/ 30) % 2] | tempo
;
293 for(t
= startt
; t
< endt
; t
++)
295 tempo
= (1 << (t
% 30));
296 account
->allowedtimeframe
[day_idx
][t
/ 60][(t
/ 30) % 2] = account
->allowedtimeframe
[7][t
/ 60][(t
/ 30) % 2] | tempo
;
301 fprintf(stderr
, "WARNING: Value '%s' is not valid for allowedtimeframe (hh:mm-hh:mm)\n", value
);
308 if(account
->allowedtimeframe_set
)
310 value
= mk_t_allowedtimeframe(account
);
311 fprintf_conf(f
, token
, "%s\n", value
);
314 else if(cfg
.http_full_cfg
)
316 fprintf_conf(f
, token
, "%s\n", "");
320 static void account_tuntab_fn(const char *token
, char *value
, void *setting
, FILE *f
)
322 TUNTAB
*ttab
= setting
;
325 if(strlen(value
) == 0)
331 chk_tuntab(value
, ttab
);
335 if((ttab
->ttdata
&& ttab
->ttdata
[0].bt_caidfrom
) || cfg
.http_full_cfg
)
337 value
= mk_t_tuntab(ttab
);
338 fprintf_conf(f
, token
, "%s\n", value
);
343 void group_fn(const char *token
, char *value
, void *setting
, FILE *f
)
345 uint64_t *grp
= setting
;
348 char *ptr1
, *saveptr1
= NULL
;
350 for(ptr1
= strtok_r(value
, ",", &saveptr1
); ptr1
; ptr1
= strtok_r(NULL
, ",", &saveptr1
))
355 { *grp
|= (((uint64_t)1) << (g
- 1)); }
359 if(*grp
|| cfg
.http_full_cfg
)
361 value
= mk_t_group(*grp
);
362 fprintf_conf(f
, token
, "%s\n", value
);
367 void services_fn(const char *token
, char *value
, void *setting
, FILE *f
)
369 SIDTABS
*sidtabs
= setting
;
373 chk_services(value
, sidtabs
);
376 value
= mk_t_service(sidtabs
);
377 if(strlen(value
) > 0 || cfg
.http_full_cfg
)
378 { fprintf_conf(f
, token
, "%s\n", value
); }
382 void class_fn(const char *token
, char *value
, void *setting
, FILE *f
)
384 CLASSTAB
*cltab
= setting
;
388 chk_cltab(value
, cltab
);
391 value
= mk_t_cltab(cltab
);
392 if(strlen(value
) > 0 || cfg
.http_full_cfg
)
394 fprintf_conf(f
, token
, "%s\n", value
);
400 static void account_fixups_fn(void *var
)
402 struct s_auth
*account
= var
;
403 if(account
->ac_users
< -1) { account
->ac_users
= DEFAULT_AC_USERS
; }
404 if(account
->ac_penalty
< -1) { account
->ac_penalty
= DEFAULT_AC_PENALTY
; }
405 if(account
->acosc_max_ecms_per_minute
< -1) { account
->acosc_max_ecms_per_minute
= -1; }
406 if(account
->acosc_max_active_sids
< -1) { account
->acosc_max_active_sids
= -1; }
407 if(account
->acosc_zap_limit
< -1) { account
->acosc_zap_limit
= -1; }
408 if(account
->acosc_penalty
< -1) { account
->acosc_penalty
= -1; }
409 if(account
->acosc_penalty_duration
< -1) { account
->acosc_penalty_duration
= -1; }
410 if(account
->acosc_delay
< -1) { account
->acosc_delay
= -1; }
411 if((account
->acosc_penalty
== 4) || ((cfg
.acosc_penalty
== 4) && (account
->acosc_penalty
== -1)))
413 account
->acosc_max_active_sids
= -1; // use global value
414 account
->acosc_zap_limit
= -1; // use global value
415 account
->acosc_penalty_duration
= -1; // use global value
417 if((account
->acosc_max_ecms_per_minute
!= -1) && (account
->acosc_max_ecms_per_minute
!= 0))
419 if(account
->acosc_max_ecms_per_minute
< 6) { account
->acosc_max_ecms_per_minute
= 6; }
420 if(account
->acosc_max_ecms_per_minute
> 20) { account
->acosc_max_ecms_per_minute
= 20; }
421 account
->acosc_penalty_duration
= (60 / account
->acosc_max_ecms_per_minute
);
427 #define OFS(X) offsetof(struct s_auth, X)
428 #define SIZEOF(X) sizeof(((struct s_auth *)0)->X)
430 static const struct config_list account_opts
[] =
433 DEF_OPT_FIXUP_FUNC(account_fixups_fn
),
435 DEF_OPT_INT8("disabled" , OFS(disabled
), 0),
436 DEF_OPT_SSTR("user" , OFS(usr
), "", SIZEOF(usr
)),
437 DEF_OPT_STR("pwd" , OFS(pwd
), NULL
),
439 DEF_OPT_STR("description" , OFS(description
), NULL
),
441 DEF_OPT_STR("hostname" , OFS(dyndns
), NULL
),
442 DEF_OPT_FUNC("caid" , OFS(ctab
), check_caidtab_fn
),
443 DEF_OPT_INT8("uniq" , OFS(uniq
), 0),
444 DEF_OPT_UINT8("sleepsend" , OFS(c35_sleepsend
), 0),
445 DEF_OPT_INT32("failban" , OFS(failban
), 0),
446 DEF_OPT_INT8("monlevel" , OFS(monlvl
), 0),
447 DEF_OPT_FUNC("sleep" , OFS(tosleep
), account_tosleep_fn
),
448 DEF_OPT_FUNC("suppresscmd08" , OFS(c35_suppresscmd08
), account_c35_suppresscmd08_fn
),
449 DEF_OPT_INT32("umaxidle" , OFS(umaxidle
), -1),
450 DEF_OPT_FUNC("keepalive" , OFS(ncd_keepalive
), account_ncd_keepalive_fn
),
451 DEF_OPT_FUNC("au" , 0, account_au_fn
),
452 DEF_OPT_UINT8("emmreassembly" , OFS(emm_reassembly
), 2),
453 DEF_OPT_FUNC("expdate" , 0, account_expdate_fn
),
454 DEF_OPT_FUNC("allowedprotocols" , 0, account_allowedprotocols_fn
),
455 DEF_OPT_FUNC("allowedtimeframe" , 0, account_allowedtimeframe_fn
),
456 DEF_OPT_FUNC("betatunnel" , OFS(ttab
), account_tuntab_fn
),
457 DEF_OPT_FUNC("group" , OFS(grp
), group_fn
),
458 DEF_OPT_FUNC("services" , OFS(sidtabs
), services_fn
),
459 DEF_OPT_INT8("preferlocalcards" , OFS(preferlocalcards
), -1),
460 DEF_OPT_FUNC_X("ident" , OFS(ftab
), ftab_fn
, FTAB_ACCOUNT
| FTAB_PROVID
),
461 DEF_OPT_FUNC_X("chid" , OFS(fchid
), ftab_fn
, FTAB_ACCOUNT
| FTAB_CHID
),
462 DEF_OPT_FUNC("class" , OFS(cltab
), class_fn
),
463 DEF_OPT_UINT32("max_connections" , OFS(max_connections
), 1),
465 DEF_OPT_INT8("cacheex" , OFS(cacheex
.mode
), 0),
466 DEF_OPT_INT8("cacheex_maxhop" , OFS(cacheex
.maxhop
), 0),
467 DEF_OPT_FUNC("cacheex_ecm_filter" , OFS(cacheex
.filter_caidtab
), cacheex_hitvaluetab_fn
),
468 DEF_OPT_UINT8("cacheex_drop_csp" , OFS(cacheex
.drop_csp
), 0),
469 DEF_OPT_UINT8("cacheex_allow_request" , OFS(cacheex
.allow_request
), 0),
470 DEF_OPT_UINT8("no_wait_time" , OFS(no_wait_time
), 0),
471 DEF_OPT_UINT8("cacheex_allow_filter" , OFS(cacheex
.allow_filter
), 1),
472 DEF_OPT_UINT8("cacheex_block_fakecws" , OFS(cacheex
.block_fakecws
), 0),
473 DEF_OPT_UINT8("disablecrccacheex" , OFS(disablecrccacheex
), 0),
474 DEF_OPT_FUNC_X("disablecrccacheex_only_for", OFS(disablecrccacheex_only_for
), ftab_fn
, FTAB_ACCOUNT
| FTAB_IGNCRCCEX4USERONLYFOR
),
477 DEF_OPT_INT32("cccmaxhops" , OFS(cccmaxhops
), DEFAULT_CC_MAXHOPS
),
478 DEF_OPT_INT8("cccreshare" , OFS(cccreshare
), DEFAULT_CC_RESHARE
),
479 DEF_OPT_INT8("cccignorereshare" , OFS(cccignorereshare
), DEFAULT_CC_IGNRSHR
),
480 DEF_OPT_INT8("cccstealth" , OFS(cccstealth
), DEFAULT_CC_STEALTH
),
483 DEF_OPT_INT32("fakedelay" , OFS(ac_fakedelay
), -1),
484 DEF_OPT_INT32("numusers" , OFS(ac_users
), DEFAULT_AC_USERS
),
485 DEF_OPT_INT8("penalty" , OFS(ac_penalty
), DEFAULT_AC_PENALTY
),
486 DEF_OPT_INT8("acosc_max_ecms_per_minute" , OFS(acosc_max_ecms_per_minute
), -1 ),
487 DEF_OPT_INT8("acosc_max_active_sids" , OFS(acosc_max_active_sids
), -1 ),
488 DEF_OPT_INT8("acosc_zap_limit" , OFS(acosc_zap_limit
), -1 ),
489 DEF_OPT_INT8("acosc_penalty" , OFS(acosc_penalty
), -1 ),
490 DEF_OPT_INT32("acosc_penalty_duration" , OFS(acosc_penalty_duration
), -1 ),
491 DEF_OPT_INT32("acosc_delay" , OFS(acosc_delay
), -1 ),
494 DEF_OPT_INT32("lb_nbest_readers" , OFS(lb_nbest_readers
), -1),
495 DEF_OPT_INT32("lb_nfb_readers" , OFS(lb_nfb_readers
), -1),
496 DEF_OPT_FUNC("lb_nbest_percaid" , OFS(lb_nbest_readers_tab
), caidvaluetab_fn
),
498 #ifdef CW_CYCLE_CHECK
499 DEF_OPT_INT8("cwc_disable" , OFS(cwc_disable
), 0),
504 void chk_account(const char *token
, char *value
, struct s_auth
*account
)
506 if(config_list_parse(account_opts
, token
, value
, account
))
508 else if(token
[0] != '#')
509 { fprintf(stderr
, "Warning: keyword '%s' in account section not recognized\n", token
); }
512 void account_set_defaults(struct s_auth
*account
)
514 config_list_set_defaults(account_opts
, account
);
517 struct s_auth
*init_userdb(void)
519 FILE *fp
= open_config_file(cs_user
);
523 struct s_auth
*authptr
= NULL
;
524 int32_t tag
= 0, nr
= 0, expired
= 0, disabled
= 0;
526 struct s_auth
*account
= NULL
;
527 struct s_auth
*probe
= NULL
;
528 if(!cs_malloc(&token
, MAXLINESIZE
))
531 while(fgets(token
, MAXLINESIZE
, fp
))
536 if((l
= strlen(trim(token
))) < 3)
538 if(token
[0] == '[' && token
[l
- 1] == ']')
541 tag
= streq("account", strtolower(token
+ 1));
542 if(!cs_malloc(&ptr
, sizeof(struct s_auth
)))
545 { account
->next
= ptr
; }
550 account_set_defaults(account
);
558 char *value
= strchr(token
, '=');
564 // check for duplicate useraccounts and make the name unique
565 if(streq(trim(strtolower(token
)), "user"))
567 for(probe
= authptr
; probe
; probe
= probe
->next
)
569 if(!strcmp(probe
->usr
, trim(value
)))
571 fprintf(stderr
, "Warning: duplicate account '%s'\n", value
);
572 strncat(value
, "_x", sizeof(probe
->usr
) - strlen(value
) - 1);
576 chk_account(trim(strtolower(token
)), trim(value
), account
);
581 for(account
= authptr
; account
; account
= account
->next
)
583 if(account
->expirationdate
&& account
->expirationdate
< time(NULL
))
585 if(account
->disabled
)
588 cs_log("userdb reloaded: %d accounts loaded, %d expired, %d disabled", nr
, expired
, disabled
);
592 int32_t init_free_userdb(struct s_auth
*ptr
)
595 for(nro
= 0; ptr
; nro
++)
597 struct s_auth
*ptr_next
;
598 ptr_next
= ptr
->next
;
599 ll_destroy(&ptr
->aureader_list
);
601 config_list_gc_values(account_opts
, ptr
);
602 ftab_clear(&ptr
->ftab
);
603 ftab_clear(&ptr
->fchid
);
604 tuntab_clear(&ptr
->ttab
);
605 caidtab_clear(&ptr
->ctab
);
606 NULLFREE(ptr
->cltab
.aclass
);
607 NULLFREE(ptr
->cltab
.bclass
);
609 cecspvaluetab_clear(&ptr
->cacheex
.filter_caidtab
);
612 caidvaluetab_clear(&ptr
->lb_nbest_readers_tab
);
617 cs_log("userdb %d accounts freed", nro
);
621 int32_t write_userdb(void)
623 struct s_auth
*account
;
624 FILE *f
= create_config_file(cs_user
);
627 for(account
= cfg
.account
; account
; account
= account
->next
)
629 fprintf(f
, "[account]\n");
630 config_list_apply_fixups(account_opts
, account
);
631 config_list_save(f
, account_opts
, account
, cfg
.http_full_cfg
);
634 return flush_config_file(f
, cs_user
);
637 void cs_accounts_chk(void)
639 struct s_auth
*account1
, *account2
;
640 struct s_auth
*new_accounts
= init_userdb();
641 cs_writelock(__func__
, &config_lock
);
642 struct s_auth
*old_accounts
= cfg
.account
;
643 for(account1
= cfg
.account
; account1
; account1
= account1
->next
)
645 for(account2
= new_accounts
; account2
; account2
= account2
->next
)
647 if(!strcmp(account1
->usr
, account2
->usr
))
649 account2
->cwfound
= account1
->cwfound
;
650 account2
->cwcache
= account1
->cwcache
;
651 account2
->cwnot
= account1
->cwnot
;
652 account2
->cwtun
= account1
->cwtun
;
653 account2
->cwignored
= account1
->cwignored
;
654 account2
->cwtout
= account1
->cwtout
;
655 account2
->emmok
= account1
->emmok
;
656 account2
->emmnok
= account1
->emmnok
;
657 account2
->firstlogin
= account1
->firstlogin
;
658 ac_copy_vars(account1
, account2
);
662 cs_reinit_clients(new_accounts
);
663 cfg
.account
= new_accounts
;
664 init_free_userdb(old_accounts
);
666 cs_writeunlock(__func__
, &config_lock
);