Skip to content

Commit c5f8b94

Browse files
committed
server config UPDATE add pw last modified oper getter
1 parent 173044c commit c5f8b94

File tree

2 files changed

+130
-0
lines changed

2 files changed

+130
-0
lines changed

src/server_config.c

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6307,4 +6307,121 @@ nc_server_config_oper_get_supported_tls_algs(const struct ly_ctx *ctx, struct ly
63076307
return nc_server_config_oper_get_algs(ctx, mod, NULL, nc_tls_supported_cipher_suites, supported_algs);
63086308
}
63096309

6310+
API int
6311+
nc_server_config_oper_get_user_password_last_modified(const struct ly_ctx *ctx, const char *ch_client,
6312+
const char *endpoint, const char *username, struct lyd_node **last_modified)
6313+
{
6314+
int rc = 0, r, locked = 0;
6315+
LY_ARRAY_COUNT_TYPE i;
6316+
struct nc_server_ssh_opts *ssh_opts = NULL;
6317+
struct nc_endpt *endpt = NULL;
6318+
struct nc_ch_client *client = NULL;
6319+
struct nc_ch_endpt *ch_endpt = NULL;
6320+
time_t found_time = 0;
6321+
char *time_str = NULL, *path = NULL;
6322+
6323+
NC_CHECK_ARG_RET(NULL, endpoint, username, last_modified, 1);
6324+
6325+
*last_modified = NULL;
6326+
6327+
/* LOCK */
6328+
pthread_rwlock_rdlock(&server_opts.config_lock);
6329+
locked = 1;
6330+
6331+
if (ch_client) {
6332+
/* find the call-home client */
6333+
LY_ARRAY_FOR(server_opts.config.ch_clients, i) {
6334+
if (!strcmp(server_opts.config.ch_clients[i].name, ch_client)) {
6335+
client = &server_opts.config.ch_clients[i];
6336+
break;
6337+
}
6338+
}
6339+
if (!client) {
6340+
ERR(NULL, "Call-home client '%s' not found.", ch_client);
6341+
rc = 1;
6342+
goto cleanup;
6343+
}
6344+
6345+
/* find the endpoint */
6346+
LY_ARRAY_FOR(client->ch_endpts, struct nc_ch_endpt, ch_endpt) {
6347+
if (!strcmp(ch_endpt->name, endpoint) && (ch_endpt->ti == NC_TI_SSH)) {
6348+
ssh_opts = ch_endpt->opts.ssh;
6349+
break;
6350+
}
6351+
}
6352+
6353+
if (!ssh_opts) {
6354+
ERR(NULL, "Endpoint '%s' with SSH transport not found in call-home client '%s'.", endpoint, ch_client);
6355+
rc = 1;
6356+
goto cleanup;
6357+
}
6358+
} else {
6359+
/* no call-home client specified, search in listening endpoints */
6360+
LY_ARRAY_FOR(server_opts.config.endpts, struct nc_endpt, endpt) {
6361+
if (!strcmp(endpt->name, endpoint) && (endpt->ti == NC_TI_SSH)) {
6362+
ssh_opts = endpt->opts.ssh;
6363+
break;
6364+
}
6365+
}
6366+
6367+
if (!ssh_opts) {
6368+
ERR(NULL, "Endpoint '%s' with SSH transport not found in listening endpoints.", endpoint);
6369+
rc = 1;
6370+
goto cleanup;
6371+
}
6372+
}
6373+
6374+
/* find the SSH user */
6375+
LY_ARRAY_FOR(ssh_opts->auth_clients, i) {
6376+
if (!strcmp(ssh_opts->auth_clients[i].username, username)) {
6377+
found_time = ssh_opts->auth_clients[i].password_last_modified;
6378+
break;
6379+
}
6380+
}
6381+
if (i == LY_ARRAY_COUNT(ssh_opts->auth_clients)) {
6382+
ERR(NULL, "SSH user '%s' not found on endpoint '%s'.", username, endpoint);
6383+
rc = 1;
6384+
goto cleanup;
6385+
}
6386+
6387+
/* UNLOCK */
6388+
pthread_rwlock_unlock(&server_opts.config_lock);
6389+
locked = 0;
6390+
6391+
if (!found_time) {
6392+
/* password has never been modified */
6393+
goto cleanup;
6394+
}
6395+
6396+
/* convert time to string */
6397+
NC_CHECK_ERR_GOTO(ly_time_time2str(found_time, NULL, &time_str), rc = 1, cleanup);
6398+
6399+
/* create the path to the oper data node */
6400+
if (ch_client) {
6401+
r = asprintf(&path, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='%s']/endpoints/"
6402+
"endpoint[name='%s']/ssh/ssh-server-parameters/client-authentication/users/user[name='%s']/password/"
6403+
"last-modified", ch_client, endpoint, username);
6404+
} else {
6405+
r = asprintf(&path, "/ietf-netconf-server:netconf-server/listen/endpoints/endpoint[name='%s']/ssh/"
6406+
"ssh-server-parameters/client-authentication/users/user[name='%s']/password/last-modified",
6407+
endpoint, username);
6408+
}
6409+
if (r == -1) {
6410+
rc = 1;
6411+
ERRMEM;
6412+
goto cleanup;
6413+
}
6414+
6415+
/* create the operational data */
6416+
NC_CHECK_ERR_GOTO(lyd_new_path(NULL, ctx, path, time_str, 0, last_modified), rc = 1, cleanup);
6417+
cleanup:
6418+
if (locked) {
6419+
/* UNLOCK */
6420+
pthread_rwlock_unlock(&server_opts.config_lock);
6421+
}
6422+
free(time_str);
6423+
free(path);
6424+
return rc;
6425+
}
6426+
63106427
#endif /* NC_ENABLED_SSH_TLS */

src/server_config.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,19 @@ int nc_server_config_oper_get_supported_ssh_algs(const struct ly_ctx *ctx, struc
348348
*/
349349
int nc_server_config_oper_get_supported_tls_algs(const struct ly_ctx *ctx, struct lyd_node **supported_algs);
350350

351+
/**
352+
* @brief Gets the last modified time of an SSH user's password.
353+
*
354+
* @param[in] ctx libyang context.
355+
* @param[in] ch_client Name of the call-home client the user is configured on. NULL if the user is on a listening endpoint.
356+
* @param[in] endpoint Name of the endpoint the user is configured on. Can be either a listening or call-home endpoint.
357+
* @param[in] username Name of the SSH user.
358+
* @param[out] last_modified Operational data tree containing the last modified time.
359+
* @return 0 on success, non-zero otherwise.
360+
*/
361+
int nc_server_config_oper_get_user_password_last_modified(const struct ly_ctx *ctx, const char *ch_client,
362+
const char *endpoint, const char *username, struct lyd_node **last_modified);
363+
351364
/**
352365
* @} Server Configuration Functions
353366
*/

0 commit comments

Comments
 (0)