891 lines
21 KiB
C
891 lines
21 KiB
C
/* login.c 21-May-96 */
|
|
|
|
/****************************************************************
|
|
* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany *
|
|
****************************************************************/
|
|
|
|
#include "net.h"
|
|
#include "nwcrypt.h"
|
|
|
|
#ifndef BLACK
|
|
#define BLACK 0
|
|
#endif
|
|
#ifndef BLUE
|
|
#define BLUE 1
|
|
#endif
|
|
#ifndef LIGHTGRAY
|
|
#define LIGHTGRAY 7
|
|
#endif
|
|
#ifndef WHITE
|
|
#define WHITE 15
|
|
#endif
|
|
|
|
static uint8 script_login_name[64];
|
|
static uint8 script_file_server[52];
|
|
|
|
static char **build_argv(char *buf, int bufsize, char *str);
|
|
extern int read_command_file(char *fstr);
|
|
extern int get_fs_name(int connid, char *name);
|
|
|
|
|
|
static uint8 login_video_attr = 0x07;
|
|
|
|
static void login_gotoxy(int x, int y)
|
|
{
|
|
REGS regs;
|
|
|
|
regs.h.ah = 0x02;
|
|
regs.h.bh = 0x00;
|
|
regs.h.dh = (uint8)(y - 1);
|
|
regs.h.dl = (uint8)(x - 1);
|
|
int86(0x10, ®s, ®s);
|
|
}
|
|
|
|
static void login_cls_attr(uint8 attr)
|
|
{
|
|
REGS regs;
|
|
|
|
regs.h.ah = 0x06;
|
|
regs.h.al = 0x00;
|
|
regs.h.bh = attr;
|
|
regs.h.ch = 0;
|
|
regs.h.cl = 0;
|
|
regs.h.dh = 24;
|
|
regs.h.dl = 79;
|
|
int86(0x10, ®s, ®s);
|
|
login_gotoxy(1, 1);
|
|
}
|
|
|
|
static void login_write_attr(int x, int y, const char *s, uint8 attr)
|
|
{
|
|
REGS regs;
|
|
int col = x;
|
|
|
|
while (*s) {
|
|
login_gotoxy(col++, y);
|
|
regs.h.ah = 0x09;
|
|
regs.h.al = (uint8)*s++;
|
|
regs.h.bh = 0;
|
|
regs.h.bl = attr;
|
|
regs.x.cx = 1;
|
|
int86(0x10, ®s, ®s);
|
|
}
|
|
login_gotoxy(col, y);
|
|
}
|
|
|
|
static void login_fill_line(int y, uint8 attr)
|
|
{
|
|
REGS regs;
|
|
|
|
login_gotoxy(1, y);
|
|
regs.h.ah = 0x09;
|
|
regs.h.al = ' ';
|
|
regs.h.bh = 0;
|
|
regs.h.bl = attr;
|
|
regs.x.cx = 80;
|
|
int86(0x10, ®s, ®s);
|
|
}
|
|
|
|
static void login_screen_normal(void)
|
|
{
|
|
login_video_attr = 0x07;
|
|
}
|
|
|
|
|
|
static int login_help(void)
|
|
{
|
|
fprintf(stdout, "\n");
|
|
fprintf(stdout, " LOGIN General Help Mars NWE\n");
|
|
fprintf(stdout, " ------------------------------------------------------------------------\n");
|
|
fprintf(stdout, " Purpose: To gain access to the network.\n");
|
|
fprintf(stdout, " Syntax: LOGIN [/VER] [[Server | Tree/][Username] [/options]\n");
|
|
fprintf(stdout, "\n");
|
|
fprintf(stdout, " To: Use:\n");
|
|
fprintf(stdout, " Login without running login scripts /NS\n");
|
|
fprintf(stdout, " Clear the screen before executing /CLS\n");
|
|
fprintf(stdout, " Specify a script file /S filename\n");
|
|
fprintf(stdout, " Display version information /VER\n");
|
|
fprintf(stdout, "\n");
|
|
fprintf(stdout, " Examples:\n");
|
|
fprintf(stdout, " LOGIN SUPERVISOR\n");
|
|
fprintf(stdout, " LOGIN MARS/SUPERVISOR\n");
|
|
fprintf(stdout, "\n");
|
|
return(0);
|
|
}
|
|
|
|
static void login_banner(void)
|
|
{
|
|
login_cls_attr(0x07); /* normal black background */
|
|
|
|
/*
|
|
* Official LOGIN shows a colored separator, title line, colored separator,
|
|
* then returns to the normal black screen for the prompt. Use blue instead
|
|
* of Novell red and show "Mars NWE".
|
|
*/
|
|
login_fill_line(1, 0x1f); /* white on blue */
|
|
login_write_attr(36, 2, "Mars NWE", 0x0f); /* white on black */
|
|
login_fill_line(3, 0x1f); /* white on blue */
|
|
|
|
login_screen_normal();
|
|
login_gotoxy(1, 4);
|
|
}
|
|
|
|
static char *skip_spaces(char *p)
|
|
{
|
|
while (*p == 32 || *p == '\t') p++;
|
|
return(p);
|
|
}
|
|
|
|
static void strip_quotes(char *s)
|
|
{
|
|
char *d = s;
|
|
char quote = 0;
|
|
|
|
while (*s) {
|
|
if (!quote && (*s == '"' || *s == '\'')) {
|
|
quote = *s++;
|
|
continue;
|
|
}
|
|
if (quote && *s == quote) {
|
|
quote = 0;
|
|
s++;
|
|
continue;
|
|
}
|
|
*d++ = *s++;
|
|
}
|
|
*d = '\0';
|
|
}
|
|
|
|
static void script_put_expanded(char *s)
|
|
{
|
|
while (s && *s) {
|
|
if (!strncmp(s, "%LOGIN_NAME", 11) || !strncmp(s, "%login_name", 11)) {
|
|
fprintf(stdout, "%s", script_login_name);
|
|
s += 11;
|
|
} else if (!strncmp(s, "%FILE_SERVER", 12) || !strncmp(s, "%file_server", 12)) {
|
|
fprintf(stdout, "%s", script_file_server);
|
|
s += 12;
|
|
} else if (!strncmp(s, "%P_STATION", 10) || !strncmp(s, "%p_station", 10)) {
|
|
fprintf(stdout, "000000000000");
|
|
s += 10;
|
|
} else {
|
|
fputc(*s++, stdout);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void script_write(char *p)
|
|
{
|
|
p = skip_spaces(p);
|
|
strip_quotes(p);
|
|
script_put_expanded(p);
|
|
fputc('\n', stdout);
|
|
}
|
|
|
|
static void script_join_args(char **argv, int argc)
|
|
{
|
|
if (argc > 2) {
|
|
char *p = argv[argc-1];
|
|
while (p-- > argv[1]) {
|
|
if (*p == '\0') *p = 32;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void script_call_line(char *line)
|
|
{
|
|
char *buf;
|
|
char **argv;
|
|
int argc = 0;
|
|
char **pp;
|
|
|
|
buf = xmalloc(512);
|
|
argv = build_argv(buf, 512, line);
|
|
if (argv != NULL) {
|
|
pp = argv;
|
|
while (*pp) {
|
|
argc++;
|
|
pp++;
|
|
}
|
|
if (argc > 0) {
|
|
upstr(argv[0]);
|
|
call_func_entry(argc, argv);
|
|
}
|
|
}
|
|
xfree(buf);
|
|
}
|
|
|
|
static int script_eval_if(char *line)
|
|
{
|
|
char tmp[512];
|
|
char *p;
|
|
char *q;
|
|
int neg = 0;
|
|
|
|
strmaxcpy(tmp, line, sizeof(tmp) - 1);
|
|
upstr(tmp);
|
|
|
|
if (strstr(tmp, "MEMBER OF") != NULL) {
|
|
if (strstr(tmp, "EVERYONE") != NULL) return(1);
|
|
return(0);
|
|
}
|
|
|
|
p = strstr(tmp, "LOGIN_NAME");
|
|
if (p != NULL) {
|
|
q = strstr(p, "<>");
|
|
if (q != NULL) neg = 1;
|
|
else q = strchr(p, '=');
|
|
|
|
if (q != NULL) {
|
|
char want[64];
|
|
char *v;
|
|
int i = 0;
|
|
|
|
q += neg ? 2 : 1;
|
|
q = skip_spaces(q);
|
|
if (*q == '"' || *q == '\'') q++;
|
|
|
|
while (*q && *q != '"' && *q != '\'' && *q != 32 && *q != '\t' && i < 63) {
|
|
want[i++] = *q++;
|
|
}
|
|
want[i] = '\0';
|
|
|
|
strmaxcpy(tmp, script_login_name, sizeof(tmp) - 1);
|
|
upstr(tmp);
|
|
|
|
if (neg) return(strcmp(tmp, want) != 0);
|
|
else return(strcmp(tmp, want) == 0);
|
|
}
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
|
|
static int login_strnicmp(char *a, char *b, int n)
|
|
{
|
|
while (n-- > 0) {
|
|
int ca = *a++;
|
|
int cb = *b++;
|
|
if (ca >= 'a' && ca <= 'z') ca -= 32;
|
|
if (cb >= 'a' && cb <= 'z') cb -= 32;
|
|
if (ca != cb) return(ca - cb);
|
|
if (!ca) return(0);
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
static int script_execute_line(char *line)
|
|
{
|
|
char work[512];
|
|
char cmd[32];
|
|
char *p;
|
|
char *arg;
|
|
int i;
|
|
|
|
strmaxcpy(work, line, sizeof(work) - 1);
|
|
p = skip_spaces(work);
|
|
|
|
if (!*p) return(0);
|
|
|
|
i = 0;
|
|
while (p[i] && p[i] != 32 && p[i] != '\t' && i < 31) {
|
|
cmd[i] = p[i];
|
|
i++;
|
|
}
|
|
cmd[i] = '\0';
|
|
upstr(cmd);
|
|
|
|
arg = skip_spaces(p + i);
|
|
|
|
if (!strcmp(cmd, "WRITE") || !strcmp(cmd, "ECHO")) {
|
|
script_write(arg);
|
|
return(0);
|
|
}
|
|
|
|
if (!strcmp(cmd, "PAUSE")) {
|
|
fprintf(stdout, "Strike any key when ready . . .");
|
|
fflush(stdout);
|
|
getch();
|
|
fprintf(stdout, "\n");
|
|
return(0);
|
|
}
|
|
|
|
if (!strcmp(cmd, "CLS")) {
|
|
login_cls_attr(0x07);
|
|
return(0);
|
|
}
|
|
|
|
if (!strcmp(cmd, "BREAK")) {
|
|
return(0);
|
|
}
|
|
|
|
if (!strcmp(cmd, "SET")) {
|
|
if (*arg) putglobenv(arg);
|
|
return(0);
|
|
}
|
|
|
|
if (!strcmp(cmd, "DRIVE")) {
|
|
arg = skip_spaces(arg);
|
|
if ((*arg >= 'A' && *arg <= 'Z') || (*arg >= 'a' && *arg <= 'z')) {
|
|
if (*arg >= 'a') setdisk(*arg - 'a');
|
|
else setdisk(*arg - 'A');
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
if (!strcmp(cmd, "MAP")) {
|
|
char up[512];
|
|
|
|
strmaxcpy(up, arg, sizeof(up) - 1);
|
|
upstr(up);
|
|
|
|
if (!strncmp(up, "DISPLAY", 7)) {
|
|
return(0);
|
|
}
|
|
|
|
if (!strncmp(up, "INS ", 4) || !strncmp(up, "INSERT ", 7)) {
|
|
char callbuf[512];
|
|
char *a = arg;
|
|
if (!login_strnicmp(up, "INS ", 4)) a += 4;
|
|
else a += 7;
|
|
sprintf(callbuf, "PATHINS %s", skip_spaces(a));
|
|
script_call_line(callbuf);
|
|
return(0);
|
|
}
|
|
|
|
if (!strncmp(up, "DEL ", 4) || !strncmp(up, "DELETE ", 7)) {
|
|
char callbuf[512];
|
|
char *a = arg;
|
|
if (!login_strnicmp(up, "DEL ", 4)) a += 4;
|
|
else a += 7;
|
|
sprintf(callbuf, "PATHDEL %s", skip_spaces(a));
|
|
script_call_line(callbuf);
|
|
return(0);
|
|
}
|
|
}
|
|
|
|
if (!strcmp(cmd, "EXIT")) {
|
|
return(1);
|
|
}
|
|
|
|
script_call_line(p);
|
|
return(0);
|
|
}
|
|
|
|
static int run_login_script(void)
|
|
{
|
|
char profile[200];
|
|
|
|
/*
|
|
* NetWare LOGIN normally executes the system login script from SYS:PUBLIC.
|
|
* Try current directory first because LOGIN.EXE is often run from PUBLIC,
|
|
* then the program path, then common SYS:PUBLIC and SYS:LOGIN paths.
|
|
*/
|
|
if (read_command_file("net$log.dat") != -2) return(0);
|
|
if (read_command_file("NET$LOG.DAT") != -2) return(0);
|
|
if (read_command_file("login") != -2) return(0);
|
|
if (read_command_file("LOGIN") != -2) return(0);
|
|
|
|
if (*prgpath) {
|
|
sprintf(profile, "%snet$log.dat", prgpath);
|
|
if (read_command_file(profile) != -2) return(0);
|
|
|
|
sprintf(profile, "%sNET$LOG.DAT", prgpath);
|
|
if (read_command_file(profile) != -2) return(0);
|
|
|
|
sprintf(profile, "%slogin", prgpath);
|
|
if (read_command_file(profile) != -2) return(0);
|
|
|
|
sprintf(profile, "%sLOGIN", prgpath);
|
|
if (read_command_file(profile) != -2) return(0);
|
|
}
|
|
|
|
if (read_command_file("\\net$log.dat") != -2) return(0);
|
|
if (read_command_file("\\NET$LOG.DAT") != -2) return(0);
|
|
|
|
if (read_command_file("\\public\\net$log.dat") != -2) return(0);
|
|
if (read_command_file("\\PUBLIC\\NET$LOG.DAT") != -2) return(0);
|
|
if (read_command_file("\\public\\login") != -2) return(0);
|
|
if (read_command_file("\\PUBLIC\\LOGIN") != -2) return(0);
|
|
|
|
if (read_command_file("f:\\public\\net$log.dat") != -2) return(0);
|
|
if (read_command_file("f:\\PUBLIC\\NET$LOG.DAT") != -2) return(0);
|
|
if (read_command_file("f:\\public\\login") != -2) return(0);
|
|
if (read_command_file("f:\\PUBLIC\\LOGIN") != -2) return(0);
|
|
|
|
if (read_command_file("\\login\\login") != -2) return(0);
|
|
if (read_command_file("\\LOGIN\\LOGIN") != -2) return(0);
|
|
if (read_command_file("\\login\\net$log.dat") != -2) return(0);
|
|
if (read_command_file("\\LOGIN\\NET$LOG.DAT") != -2) return(0);
|
|
|
|
return(-2);
|
|
}
|
|
|
|
|
|
static int do_change_object_passwd(char *name,
|
|
uint16 objtyp,
|
|
char *oldpassword,
|
|
char *newpassword)
|
|
|
|
{
|
|
uint8 key[8];
|
|
|
|
if (!ncp_17_17(key)) {
|
|
uint32 objid = ncp_17_35(name, objtyp);
|
|
if (objid) {
|
|
uint8 oldpwd[16]; /* old passwd as stored by server */
|
|
uint8 newpwd[16]; /* new passwd as stored by server */
|
|
uint8 cryptkey[8];
|
|
uint8 tmpid[4];
|
|
uint8 passwdx;
|
|
int newlen;
|
|
|
|
memcpy(cryptkey, key, 8);
|
|
U32_TO_BE32(objid, tmpid);
|
|
|
|
shuffle(tmpid, oldpassword, strlen(oldpassword), oldpwd);
|
|
shuffle(tmpid, newpassword, strlen(newpassword), newpwd);
|
|
|
|
nw_encrypt(cryptkey, oldpwd, cryptkey);
|
|
|
|
/*
|
|
* Same keyed change password transformation as ncpfs
|
|
* ncp_change_login_passwd(): encrypt both 8-byte halves of the
|
|
* stored new password using the stored old password as key material.
|
|
* newpassencrypt() intentionally mutates oldpwd; the passwd length
|
|
* byte must be calculated afterwards, just like ncpfs does it.
|
|
*/
|
|
newpassencrypt(oldpwd, newpwd);
|
|
newpassencrypt(oldpwd + 8, newpwd + 8);
|
|
|
|
newlen = strlen(newpassword);
|
|
if (newlen > 63) newlen = 63;
|
|
passwdx = (uint8)(((newlen ^ oldpwd[0] ^ oldpwd[1]) & 0x7f) | 0x40);
|
|
|
|
if (!ncp_17_4b(cryptkey, name, objtyp, passwdx, newpwd)) {
|
|
;;
|
|
return(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Fallback for old servers/requesters where Get Encryption Key is not
|
|
* available. Keep the original unencrypted behavior as fallback only.
|
|
*/
|
|
if (!ncp_17_40(name, objtyp, oldpassword, newpassword)) {
|
|
;;
|
|
return(0);
|
|
}
|
|
|
|
return(-1);
|
|
}
|
|
|
|
static int do_object_login(char *name, uint16 objtyp, char *password, int option)
|
|
{
|
|
uint8 key[8];
|
|
if (!(option & 1) && !ncp_17_17(key)) {
|
|
uint32 objid = ncp_17_35(name, objtyp);
|
|
if (objid) {
|
|
uint8 buff[128];
|
|
uint8 encrypted[8];
|
|
uint8 tmpid[4];
|
|
U32_TO_BE32(objid, tmpid);
|
|
shuffle(tmpid, password, strlen(password), buff);
|
|
nw_encrypt(key, buff, encrypted);
|
|
if (!ncp_17_18(encrypted, name, objtyp)) {
|
|
;;
|
|
return(0);
|
|
}
|
|
}
|
|
} else { /* now we use old unencrypted algorithmus */
|
|
if (!ncp_17_14(name, objtyp, password)) {
|
|
return(0);
|
|
}
|
|
}
|
|
return(-1);
|
|
}
|
|
|
|
static void beep(void)
|
|
{
|
|
fprintf(stdout, "\007");
|
|
}
|
|
|
|
static int get_raw_str(uint8 *s, int maxlen, int doecho)
|
|
/* returns len of readed str */
|
|
{
|
|
int len = 0;
|
|
while (len < maxlen){
|
|
int key = getch();
|
|
if (key == '\r' || key == '\n') break;
|
|
switch (key) {
|
|
case 8 : if (len) {
|
|
--len;
|
|
--s;
|
|
if (doecho) {
|
|
fprintf(stdout, "\010 \010");
|
|
fflush(stdout);
|
|
}
|
|
} else beep();
|
|
continue;
|
|
|
|
case '\t': beep();
|
|
continue;
|
|
|
|
default : *s++=(uint8)key;
|
|
len++;
|
|
break;
|
|
} /* switch */
|
|
if (doecho) {
|
|
fprintf(stdout, "%c", (uint8)key);
|
|
fflush(stdout);
|
|
}
|
|
}
|
|
*s='\0';
|
|
return(len);
|
|
}
|
|
|
|
static void getstr(char *what, char *str, int rsize, int doecho)
|
|
{
|
|
fprintf(stdout, "%s: ", what);
|
|
fflush(stdout);
|
|
get_raw_str(str, rsize, doecho);
|
|
fprintf(stdout, "\n");
|
|
}
|
|
|
|
static int login_usage(void)
|
|
{
|
|
return(login_help());
|
|
}
|
|
|
|
int func_login(int argc, char *argv[], int mode)
|
|
{
|
|
int result=-1;
|
|
int option=0;
|
|
uint8 uname[200];
|
|
uint8 upasswd[200];
|
|
SEARCH_VECTOR save_drives;
|
|
int interactive_login = 0;
|
|
int no_script = 0;
|
|
|
|
if (argc > 1) {
|
|
if (!strcmp(argv[1], "/?") || !strcmp(argv[1], "-?") || !strcmp(argv[1], "?"))
|
|
return(login_help());
|
|
if (!strcmp(argv[1], "/VER") || !strcmp(argv[1], "-VER")) {
|
|
fprintf(stdout, "Mars NWE LOGIN 0.99\n");
|
|
return(0);
|
|
}
|
|
}
|
|
|
|
if (argc > 1) {
|
|
if (argv[1][0] == '-' || argv[1][0] == '/') {
|
|
if (argv[1][1] == 'u' || argv[1][1] == 'U') option |= 1;
|
|
else if (!strcmp(argv[1], "/NS") || !strcmp(argv[1], "-NS")) no_script = 1;
|
|
else if (!strcmp(argv[1], "/CLS") || !strcmp(argv[1], "-CLS")) login_cls_attr(0x07);
|
|
else return(login_usage());
|
|
argc--;
|
|
argv++;
|
|
}
|
|
}
|
|
get_search_drive_vektor(save_drives);
|
|
remove_nwpathes();
|
|
if (argc > 1) strmaxcpy(uname, argv[1], sizeof(uname) -1);
|
|
else uname[0]='\0';
|
|
if (argc > 2) strmaxcpy(upasswd, argv[2], sizeof(upasswd) -1);
|
|
else upasswd[0]='\0';
|
|
|
|
if (!uname[0]) {
|
|
interactive_login = 1;
|
|
login_banner();
|
|
}
|
|
|
|
while (result) {
|
|
if (!uname[0]) getstr("Enter your login name", uname, sizeof(uname)-1, 1);
|
|
if (uname[0]) {
|
|
upstr(uname);
|
|
upstr(upasswd);
|
|
if ((result = do_object_login(uname, 0x1, upasswd, option)) < 0 && !*upasswd) {
|
|
getstr("Enter your password", upasswd, sizeof(upasswd)-1, 0);
|
|
upstr(upasswd);
|
|
result = do_object_login(uname, 0x1, upasswd, option);
|
|
}
|
|
if (result < 0) {
|
|
fprintf(stdout, "Login incorrect\n\n");
|
|
uname[0] = '\0';
|
|
upasswd[0] = '\0';
|
|
}
|
|
} else break;
|
|
}
|
|
if (result > -1) {
|
|
strmaxcpy(script_login_name, uname, sizeof(script_login_name) - 1);
|
|
|
|
if (get_fs_name(1, script_file_server))
|
|
strcpy(script_file_server, "MARS");
|
|
|
|
if (interactive_login)
|
|
fprintf(stdout, "You are attached to server %s.\n", script_file_server);
|
|
|
|
remove_nwpathes();
|
|
|
|
if (!no_script)
|
|
run_login_script();
|
|
} else {
|
|
(void)set_search_drive_vektor(save_drives);
|
|
}
|
|
return(result);
|
|
}
|
|
|
|
int func_logout(int argc, char *argv[], int mode)
|
|
{
|
|
remove_nwpathes();
|
|
if (logout()) {
|
|
fprintf(stderr, "logout=%d\n", neterrno);
|
|
return(1);
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
|
|
int func_passwd(int argc, char *argv[], int mode)
|
|
{
|
|
int result=0;
|
|
uint8 uname[100];
|
|
uint8 upasswd[130];
|
|
uint32 my_obj_id;
|
|
|
|
if (ncp_14_46(&my_obj_id) < 0 || my_obj_id == MAX_U32 || !my_obj_id) {
|
|
fprintf(stderr, "Cannot get actual user id\n");
|
|
result = -1;
|
|
}
|
|
|
|
if (!result && argc > 1) {
|
|
uint32 obj_id;
|
|
strmaxcpy(uname, argv[1], sizeof(uname) -1);
|
|
upstr(uname);
|
|
obj_id = ncp_17_35(uname, 1);
|
|
if (!obj_id) {
|
|
fprintf(stderr, "Unkwown user: %s\n", uname);
|
|
return(-1);
|
|
}
|
|
} else if (!result) {
|
|
uint16 obj_typ;
|
|
if (ncp_17_36(my_obj_id, uname, &obj_typ) || obj_typ != 1) {
|
|
fprintf(stderr, "Cannot get actual username\n");
|
|
result=-1;
|
|
}
|
|
}
|
|
if (!result && *uname) {
|
|
uint8 newpasswd[130];
|
|
uint8 newpasswd2[130];
|
|
if (my_obj_id == 1L) *upasswd='\0';
|
|
else {
|
|
getstr("Old password", upasswd, sizeof(upasswd)-1, 0);
|
|
upstr(upasswd);
|
|
}
|
|
getstr("New password", newpasswd, sizeof(newpasswd)-1, 0);
|
|
getstr("New password again", newpasswd2, sizeof(newpasswd2)-1, 0);
|
|
if (!strcmp(newpasswd, newpasswd2)) {
|
|
upstr(uname);
|
|
upstr(newpasswd);
|
|
if (do_change_object_passwd(uname, 1, upasswd, newpasswd) < 0)
|
|
result = -1;
|
|
} else {
|
|
result = -1;
|
|
fprintf(stderr, "Password misspelled\n");
|
|
}
|
|
}
|
|
if (result < 0) fprintf(stderr, "Password not changed");
|
|
return(result);
|
|
}
|
|
|
|
static int get_line(FILE *f, char *buff, int bufsize, uint8 *str, int strsize)
|
|
/* returns command line or -1 if ends */
|
|
{
|
|
if ((FILE*) NULL != f) {
|
|
while (fgets(buff, bufsize, f) != NULL){
|
|
char *p = buff;
|
|
char *beg = NULL;
|
|
char c;
|
|
int len=0;
|
|
while (0 != (c = *p++) && c != '\n' && c != '\r' && c != '#') {
|
|
if (!beg){
|
|
if (c != '\t' && c != 32) {
|
|
beg = p - 1;
|
|
len = 1;
|
|
}
|
|
} else ++len;
|
|
}
|
|
if (len) {
|
|
strmaxcpy((uint8*)str, (uint8*)beg, min(len, strsize-1));
|
|
return(0);
|
|
}
|
|
}
|
|
}
|
|
return(-1);
|
|
}
|
|
|
|
|
|
|
|
static char **build_argv(char *buf, int bufsize, char *command)
|
|
/* routine returns **argv for use with execv routines */
|
|
/* buf will contain the path component */
|
|
{
|
|
int len = strlen(command);
|
|
int offset = ((len+4) / 4) * 4; /* aligned offset for **argv */
|
|
int components = (bufsize - offset) / 4;
|
|
if (components > 1) { /* minimal argv[0] + NULL */
|
|
char **argv = (char **)(buf+offset);
|
|
char **pp = argv;
|
|
char *p = buf;
|
|
char c;
|
|
int i=0;
|
|
--components;
|
|
memcpy(buf, command, len);
|
|
memset(buf+len, 0, bufsize - len);
|
|
*pp = p;
|
|
while ((0 != (c = *p++)) && i < components) {
|
|
if (c == 32 || c == '\t') {
|
|
*(p-1) = '\0';
|
|
if (*p != 32 && *p != '\t') {
|
|
*(++pp)=p;
|
|
i++;
|
|
}
|
|
} else if (!i && c == '/') { /* here i must get argv[0] */
|
|
*pp=p;
|
|
}
|
|
}
|
|
return(argv);
|
|
}
|
|
return(NULL);
|
|
}
|
|
|
|
int read_command_file(char *fstr)
|
|
{
|
|
FILE *f=fopen(fstr, "r");
|
|
int result=-1;
|
|
|
|
if (f != NULL) {
|
|
char *linebuf = xmalloc(512);
|
|
char *buf = xmalloc(512);
|
|
int stack[16];
|
|
int level = 0;
|
|
int active = 1;
|
|
|
|
while (get_line(f, buf, 512, linebuf, 512) > -1) {
|
|
char tmp[512];
|
|
char *p;
|
|
|
|
strmaxcpy(tmp, linebuf, sizeof(tmp) - 1);
|
|
p = skip_spaces(tmp);
|
|
upstr(p);
|
|
|
|
if (!strncmp(p, "IF ", 3)) {
|
|
if (level < 16) {
|
|
stack[level++] = active;
|
|
active = active && script_eval_if(linebuf);
|
|
}
|
|
result = 0;
|
|
continue;
|
|
}
|
|
|
|
if (!strcmp(p, "END") || !strncmp(p, "END ", 4)) {
|
|
if (level > 0) active = stack[--level];
|
|
result = 0;
|
|
continue;
|
|
}
|
|
|
|
if (!active) {
|
|
result = 0;
|
|
continue;
|
|
}
|
|
|
|
if (script_execute_line(linebuf))
|
|
break;
|
|
|
|
result = 0;
|
|
}
|
|
|
|
fclose(f);
|
|
xfree(linebuf);
|
|
xfree(buf);
|
|
} else result=-2;
|
|
|
|
return(result);
|
|
}
|
|
|
|
int func_profile(int argc, char *argv[], int mode)
|
|
{
|
|
if (argc < 2) {
|
|
fprintf(stderr, "usage:\t%s fn\n", funcname);
|
|
return(-1);
|
|
}
|
|
if (read_command_file(argv[1]) == -2) {
|
|
fprintf(stderr, "command file %s not found\n", argv[1]);
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
int func_cwd(int argc, char *argv[], int mode)
|
|
{
|
|
char pathname[65];
|
|
int len;
|
|
if (argc < 2) {
|
|
fprintf(stderr, "usage:\t%s path\n", funcname);
|
|
return(-1);
|
|
}
|
|
strmaxcpy(pathname, argv[1], sizeof(pathname) -1);
|
|
korrpath(pathname);
|
|
if (0 != (len = strlen(pathname))) {
|
|
char *p=pathname+len-1;
|
|
if (*p == '/' || *p == ':') {
|
|
*(++p) = '.';
|
|
*(++p) = '\0';
|
|
len++;
|
|
}
|
|
if (!chdir(pathname)) {
|
|
if (len > 2 && *(pathname+1) == ':') /* device changed */
|
|
setdisk(*pathname - 'a' );
|
|
} else {
|
|
fprintf(stderr, "cannot chdir to %s\n", pathname);
|
|
return(1);
|
|
}
|
|
return(0);
|
|
} else return(-1);
|
|
}
|
|
|
|
int func_echo(int argc, char *argv[], int mode)
|
|
{
|
|
if (argc > 1)
|
|
fprintf(stdout, "%s\n", argv[1]);
|
|
return(0);
|
|
}
|
|
|
|
int func_exec(int argc, char *argv[], int mode)
|
|
{
|
|
if (argc > 1) {
|
|
char *buf = xmalloc(512);
|
|
char *buff = xmalloc(512);
|
|
char *p = buff;
|
|
int k = 0;
|
|
char **nargv;
|
|
while (++k < argc) {
|
|
strcpy(p, argv[k]);
|
|
p += strlen(argv[k]);
|
|
*p++ = 32;
|
|
*p = '\0';
|
|
}
|
|
nargv=build_argv(buf, 512, buff);
|
|
xfree(buff);
|
|
if (nargv != NULL) {
|
|
if (!mode)
|
|
spawnvp(P_WAIT, buf, (const char *const *)nargv);
|
|
else
|
|
execvp(buf, (const char *const *)nargv);
|
|
}
|
|
xfree(buf);
|
|
}
|
|
return(0);
|
|
}
|
|
|