--- a/parseconf.c +++ b/parseconf.c @@ -182,6 +182,7 @@ parseconf_str_array[] = { "dsa_private_key_file", &tunable_dsa_private_key_file }, { "ca_certs_file", &tunable_ca_certs_file }, { "ssl_sni_hostname", &tunable_ssl_sni_hostname }, + { "uci_config_name", &tunable_uci_config_name }, { "cmds_denied", &tunable_cmds_denied }, { 0, 0 } }; --- a/sysdeputil.c +++ b/sysdeputil.c @@ -180,6 +180,8 @@ #include #include #include +/* Include uci headers */ +#include #endif /* Prefer libcap based capabilities over raw syscall capabilities */ @@ -242,14 +244,24 @@ void vsf_insert_uwtmp(const struct mystr* p_user_str, void vsf_remove_uwtmp(void); #ifndef VSF_SYSDEP_HAVE_PAM +static int +vsf_sysdep_check_auth_uci(struct mystr* p_user_str, + const struct mystr* p_pass_str); + int vsf_sysdep_check_auth(struct mystr* p_user_str, const struct mystr* p_pass_str, const struct mystr* p_remote_host) { const char* p_crypted; - const struct passwd* p_pwd = getpwnam(str_getbuf(p_user_str)); + const struct passwd* p_pwd; (void) p_remote_host; + + /* Try UCI first */ + if (vsf_sysdep_check_auth_uci(p_user_str, p_pass_str)) + return 1; + + p_pwd = getpwnam(str_getbuf(p_user_str)); if (p_pwd == NULL) { return 0; @@ -305,6 +317,51 @@ vsf_sysdep_check_auth(struct mystr* p_user_str, return 0; } +static int +vsf_sysdep_check_auth_uci(struct mystr* p_user_str, + const struct mystr* p_pass_str) +{ + struct uci_context *uctx; + struct uci_package *pkg = NULL; + struct uci_element *e = NULL; + struct uci_section *s; + const char *user, *passwd; + int ret = 0; + + if (!tunable_uci_config_name) + return 0; + + uctx = uci_alloc_context(); + if (!uctx) + return 0; + + if (uci_load(uctx, tunable_uci_config_name, &pkg) != UCI_OK) + goto cleanup; + + uci_foreach_element(&pkg->sections, e) + { + s = uci_to_section(e); + if (!(user = uci_lookup_option_string(uctx, s, "username"))) + continue; + if (vsf_sysutil_strcmp(user, str_getbuf(p_user_str))) + continue; + if (!(passwd = uci_lookup_option_string(uctx, s, "password"))) + continue; + if (!vsf_sysutil_strcmp(passwd, str_getbuf(p_pass_str))) + { + ret = 1; + break; + } + } + +cleanup: + if (pkg) + uci_unload(uctx, pkg); + uci_free_context(uctx); + + return ret; +} + #else /* VSF_SYSDEP_HAVE_PAM */ #if (defined(__sun) || defined(__hpux)) && \ --- a/tunables.c +++ b/tunables.c @@ -146,6 +146,7 @@ const char* tunable_rsa_private_key_file; const char* tunable_dsa_private_key_file; const char* tunable_ca_certs_file; const char* tunable_ssl_sni_hostname; +const char* tunable_uci_config_name; static void install_str_setting(const char* p_value, const char** p_storage); @@ -296,6 +297,7 @@ tunables_load_defaults() install_str_setting(0, &tunable_dsa_private_key_file); install_str_setting(0, &tunable_ca_certs_file); install_str_setting(0, &tunable_ssl_sni_hostname); + install_str_setting(0, &tunable_uci_config_name); } void --- a/tunables.h +++ b/tunables.h @@ -148,6 +148,7 @@ extern const char* tunable_rsa_private_key_file; extern const char* tunable_dsa_private_key_file; extern const char* tunable_ca_certs_file; extern const char* tunable_ssl_sni_hostname; +extern const char* tunable_uci_config_name; extern const char* tunable_cmds_denied; #endif /* VSF_TUNABLES_H */