Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F4512054
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/vty.h b/vty.h
index 287ed07d..8935b549 100644
--- a/vty.h
+++ b/vty.h
@@ -1,31 +1,32 @@
#ifndef __VTY_H__
#define __VTY_H__
#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
#define KNET_VTY_DEFAULT_PORT 50000
#define KNET_VTY_DEFAULT_MAX_CONN 4
#define KNET_VTY_TOTAL_MAX_CONN 16
struct knet_vty {
pthread_t vty_thread;
struct sockaddr_storage src_sa;
socklen_t src_sa_len;
char username[64];
+ int user_can_enable;
int vty_sock;
int conn_num;
int active;
};
int knet_vty_main_loop(const char *configfile, const char *ip_addr,
const unsigned short port);
int knet_vty_init_listener(const char *address, const unsigned short port);
void knet_vty_close_listener(int listener_fd);
int knet_vty_set_max_connections(const int max_connections);
#endif
diff --git a/vty_auth.c b/vty_auth.c
index 2671939d..17a53c84 100644
--- a/vty_auth.c
+++ b/vty_auth.c
@@ -1,200 +1,278 @@
#include "config.h"
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
+#include <sys/types.h>
+#include <grp.h>
#include <security/pam_appl.h>
#include <security/pam_misc.h>
#include "utils.h"
#include "vty_auth.h"
#include "vty_utils.h"
static int knet_pam_misc_conv(int num_msg, const struct pam_message **msgm,
struct pam_response **response, void *appdata_ptr)
{
int count = 0;
struct pam_response *reply;
struct knet_vty *vty = (struct knet_vty *)appdata_ptr;
if (num_msg <= 0)
return PAM_CONV_ERR;
reply = (struct pam_response *) calloc(num_msg, sizeof(struct pam_response));
if (reply == NULL)
return PAM_CONV_ERR;
for (count=0; count < num_msg; ++count) {
unsigned char readbuf[VTY_MAX_BUFFER_SIZE];
char *string=NULL;
int nc;
memset(readbuf, 0, sizeof(readbuf));
switch (msgm[count]->msg_style) {
case PAM_PROMPT_ECHO_OFF:
if (knet_vty_set_echo(vty, 0) < 0) {
knet_vty_write(vty, "Unable to turn off terminal/telnet echo");
goto failed_conversation;
}
knet_vty_write(vty, "%s", msgm[count]->msg);
nc = knet_vty_read(vty, readbuf, sizeof(readbuf));
if (nc < 0)
goto failed_conversation;
if (knet_vty_set_echo(vty, 1) < 0) {
/* doesn't really make a lot of sense tho.... */
knet_vty_write(vty, "Unable to turn on terminal/telnet echo");
goto failed_conversation;
}
knet_vty_write(vty, "\n");
readbuf[nc-2] = 0;
string = strdup((const char*)readbuf);
if (!string)
goto failed_conversation;
break;
case PAM_PROMPT_ECHO_ON:
knet_vty_write(vty, "\n%s", msgm[count]->msg);
nc = knet_vty_read(vty, readbuf, sizeof(readbuf));
if (nc < 0)
goto failed_conversation;
readbuf[nc-2] = 0;
string = strdup((const char*)readbuf);
if (!string)
goto failed_conversation;
break;
case PAM_ERROR_MSG:
log_error("Received PAM error message %s", msgm[count]->msg);
knet_vty_write(vty, "%s", msgm[count]->msg);
break;
case PAM_TEXT_INFO:
log_error("Received PAM text info: %s", msgm[count]->msg);
knet_vty_write(vty, "%s", msgm[count]->msg);
break;
default:
log_error("Unknown PAM conversation message");
knet_vty_write(vty, "Unknown PAM conversation message");
goto failed_conversation;
}
if (string) {
reply[count].resp_retcode = 0;
reply[count].resp = string;
string = NULL;
}
}
*response = reply;
reply = NULL;
return PAM_SUCCESS;
failed_conversation:
log_error("PAM conversation error");
knet_vty_write(vty, "PAM conversation error");
if (reply) {
for (count=0; count < num_msg; ++count) {
if (reply[count].resp == NULL)
continue;
switch (msgm[count]->msg_style) {
case PAM_PROMPT_ECHO_ON:
case PAM_PROMPT_ECHO_OFF:
_pam_overwrite(reply[count].resp);
free(reply[count].resp);
break;
case PAM_BINARY_PROMPT:
{
void *bt_ptr = reply[count].resp;
pam_binary_handler_free(appdata_ptr, bt_ptr);
break;
}
case PAM_ERROR_MSG:
case PAM_TEXT_INFO:
free(reply[count].resp);
}
}
free(reply);
reply = NULL;
}
return PAM_CONV_ERR;
}
static int knet_vty_get_pam_user(struct knet_vty *vty, pam_handle_t *pamh)
{
const void *value;
int err;
memset(vty->username, 0, sizeof(vty->username));
err = pam_get_item(pamh, PAM_USER, &value);
if (err != PAM_SUCCESS)
return err;
strncpy(vty->username, (const char*)value, 32);
return 0;
}
-int knet_vty_auth_user(struct knet_vty *vty, const char *user)
+static int knet_vty_pam_auth_user(struct knet_vty *vty, const char *user)
{
pam_handle_t *pamh=NULL;
struct pam_conv conv;
int err;
int retry = 1;
conv.conv = knet_pam_misc_conv;
conv.appdata_ptr = (void *)vty;
retry_auth:
err = pam_start("kronosnet", user, &conv, &pamh);
if (err != PAM_SUCCESS) {
log_error("PAM fatal error: %s", pam_strerror(pamh, err));
knet_vty_write(vty, "PAM fatal error: %s",
pam_strerror(pamh, err));
goto out_fatal;
}
err = pam_authenticate(pamh, 0);
if (knet_vty_get_pam_user(vty, pamh) != PAM_SUCCESS) {
log_error("PAM: unable to get PAM_USER: %s",
pam_strerror(pamh, err));
knet_vty_write(vty, "PAM: unable to get PAM_USER: %s",
pam_strerror(pamh, err));
goto out_clean;
}
if (err != PAM_SUCCESS) {
log_info("User: %s failed to authenticate on vty(%d) attempt %d",
vty->username, vty->conn_num, retry);
goto out_clean;
}
err = pam_acct_mgmt(pamh, 0);
if (err != PAM_SUCCESS) {
log_info("User: %s failed to authenticate on vty(%d) attempt %d",
vty->username, vty->conn_num, retry);
goto out_clean;
}
out_clean:
if (pamh) {
pam_end(pamh, err);
pamh = NULL;
}
if ((err != PAM_SUCCESS) && (retry < AUTH_MAX_RETRY)) {
retry++;
goto retry_auth;
}
out_fatal:
knet_vty_write(vty, "\n");
return err;
}
+
+static int knet_vty_group_check(struct knet_vty *vty)
+{
+ struct group grp;
+ char *buf;
+ size_t buflen;
+ long int initlen;
+ struct group *result;
+ char *gr_mem;
+ int err, i;
+
+ errno = 0;
+ initlen = sysconf(_SC_GETGR_R_SIZE_MAX);
+ if ((initlen < 0) && (errno == EINVAL))
+ return -1;
+
+ if (initlen < 0)
+ initlen = 1024;
+
+ buflen = (size_t) initlen;
+
+ buf = malloc(buflen);
+ if (!buf)
+ return -1;
+
+ /* TODO make default group user configurable */
+ while ((err = getgrnam_r("kronosnetadm", &grp, buf, buflen, &result)) == ERANGE) {
+ size_t newlen = 2 * buflen;
+ char *newbuf;
+
+ newbuf = realloc(buf, newlen);
+ if (!newbuf) {
+ err = -1;
+ goto out_clean;
+ }
+ buf = newbuf;
+ }
+ if (err)
+ goto out_clean;
+
+ if (result == NULL) {
+ errno = EACCES;
+ log_error("No kronosnetadm group found on the system");
+ knet_vty_write(vty, "No kronosnetadm group found on the system\n");
+ err = -1;
+ goto out_clean;
+ }
+
+ gr_mem = *grp.gr_mem;
+
+ i = 1;
+ while(gr_mem != NULL) {
+ if (!strcmp(vty->username, gr_mem)) {
+ vty->user_can_enable = 1;
+ break;
+ }
+ gr_mem = *(grp.gr_mem + i);
+ i++;
+ }
+
+out_clean:
+ free(buf);
+
+ return err;
+}
+
+int knet_vty_auth_user(struct knet_vty *vty, const char *user)
+{
+ int err;
+
+ err = knet_vty_pam_auth_user(vty, user);
+ if (err != PAM_SUCCESS)
+ return err;
+
+ return knet_vty_group_check(vty);
+}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Wed, Jun 25, 3:49 AM (1 d, 1 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1952062
Default Alt Text
(7 KB)
Attached To
Mode
rK kronosnet
Attached
Detach File
Event Timeline
Log In to Comment