From 0e8fd3398771da2f016d72830179507f3edda51b Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Sat, 4 May 1996 07:50:46 +0000 Subject: Initial version imported to CVS (This used to be commit 291551d80711daab7b7581720bcd9a08d6096517) --- source3/utils/nmblookup.c | 217 ++++++++++++++++++++++ source3/utils/smbpasswd.c | 456 ++++++++++++++++++++++++++++++++++++++++++++++ source3/utils/status.c | 258 ++++++++++++++++++++++++++ source3/utils/testparm.c | 113 ++++++++++++ source3/utils/testprns.c | 72 ++++++++ 5 files changed, 1116 insertions(+) create mode 100644 source3/utils/nmblookup.c create mode 100644 source3/utils/smbpasswd.c create mode 100644 source3/utils/status.c create mode 100644 source3/utils/testparm.c create mode 100644 source3/utils/testprns.c (limited to 'source3/utils') diff --git a/source3/utils/nmblookup.c b/source3/utils/nmblookup.c new file mode 100644 index 0000000000..aa43173332 --- /dev/null +++ b/source3/utils/nmblookup.c @@ -0,0 +1,217 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + NBT client - used to lookup netbios names + Copyright (C) Andrew Tridgell 1994-1995 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifdef SYSLOG +#undef SYSLOG +#endif + +#include "includes.h" +#include "nameserv.h" + +extern int DEBUGLEVEL; + +extern pstring scope; + +extern struct in_addr bcast_ip; +extern pstring myhostname; + +static BOOL got_bcast = False; + +int ServerFD= -1; + +/**************************************************************************** + open the socket communication + **************************************************************************/ +static BOOL open_sockets(void) +{ + struct hostent *hp; + + /* get host info */ + if ((hp = Get_Hostbyname(myhostname)) == 0) + { + DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",myhostname)); + return False; + } + + ServerFD = open_socket_in(SOCK_DGRAM, 0,3); + + if (ServerFD == -1) + return(False); + + set_socket_options(ServerFD,"SO_BROADCAST"); + + DEBUG(3, ("Socket opened.\n")); + return True; +} + + +/**************************************************************************** + initialise connect, service and file structs +****************************************************************************/ +static BOOL init_structs(void ) +{ + struct in_addr myip; + + if (!get_myname(myhostname,&myip)) + return(False); + + /* Read the broadcast address from the interface */ + { + struct in_addr ip0,ip2; + + ip0 = myip; + + if (!got_bcast) { + get_broadcast(&ip0,&bcast_ip,&ip2); + + DEBUG(2,("Using broadcast %s\n",inet_ntoa(bcast_ip))); + } + } + + return True; +} + +/**************************************************************************** +usage on the program +****************************************************************************/ +static void usage(void) +{ + printf("Usage: nmblookup [-M] [-B bcast address] [-d debuglevel] name\n"); + printf("Version %s\n",VERSION); + printf("\t-d debuglevel set the debuglevel\n"); + printf("\t-B broadcast address the address to use for broadcasts\n"); + printf("\t-M searches for a master browser\n"); + printf("\t-S lookup node status as well\n"); + printf("\n"); +} + + +/**************************************************************************** + main program +****************************************************************************/ +int main(int argc,char *argv[]) +{ + int opt; + unsigned int lookup_type = 0x20; + pstring lookup; + extern int optind; + extern char *optarg; + BOOL find_master=False; + BOOL find_status=False; + int i; + + DEBUGLEVEL = 1; + *lookup = 0; + + TimeInit(); + + setup_logging(argv[0],True); + + charset_initialise(); + + while ((opt = getopt(argc, argv, "p:d:B:i:SMh")) != EOF) + switch (opt) + { + case 'B': + { + unsigned long a = interpret_addr(optarg); + putip((char *)&bcast_ip,(char *)&a); + got_bcast = True; + } + break; + case 'i': + strcpy(scope,optarg); + strupper(scope); + break; + case 'M': + find_master = True; + break; + case 'S': + find_status = True; + break; + case 'd': + DEBUGLEVEL = atoi(optarg); + break; + case 'h': + usage(); + exit(0); + break; + default: + usage(); + exit(1); + } + + if (argc < 2) { + usage(); + exit(1); + } + + init_structs(); + if (!open_sockets()) return(1); + + DEBUG(1,("Sending queries to %s\n",inet_ntoa(bcast_ip))); + + + for (i=optind;i= (PTR_DIFF(p, linebuf) + 33)) && (p[32] == ':')) { + /* NT Entry was valid - even if 'X' or '*', can be overwritten */ + *got_valid_nt_entry = True; + if (*p != '*' && *p != 'X') { + if(gethexpwd(p,smbntpwd)) + pw_buf.smb_nt_passwd = smbntpwd; + } + } + pw_buf.smb_name = user_name; + pw_buf.smb_userid = uidval; + pw_buf.smb_passwd = NULL; /* No password */ + return (&pw_buf); + } + if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) + return (False); + + if (p[32] != ':') + return (False); + + if (!strncasecmp(p, "NO PASSWORD", 11)) { + pw_buf.smb_passwd = NULL; /* No password */ + } else { + if(!gethexpwd(p,smbpwd)) + return False; + pw_buf.smb_passwd = smbpwd; + } + + pw_buf.smb_name = user_name; + pw_buf.smb_userid = uidval; + pw_buf.smb_nt_passwd = NULL; + *got_valid_nt_entry = False; + *valid_old_pwd = True; + + /* Now check if the NT compatible password is + available. */ + p += 33; /* Move to the first character of the line after + the lanman password. */ + if ((linebuf_len >= (PTR_DIFF(p, linebuf) + 33)) && (p[32] == ':')) { + /* NT Entry was valid - even if 'X' or '*', can be overwritten */ + *got_valid_nt_entry = True; + if (*p != '*' && *p != 'X') { + if(gethexpwd(p,smbntpwd)) + pw_buf.smb_nt_passwd = smbntpwd; + } + } + return &pw_buf; + } + return NULL; +} + +/* + * Print command usage on stderr and die. + */ +void +usage(char *name) +{ + fprintf(stderr, "Usage is : %s [username]\n", name); + exit(1); +} + +int main(int argc, char **argv) +{ + int real_uid; + struct passwd *pwd; + fstring old_passwd; + uchar old_p16[16]; + uchar old_nt_p16[16]; + fstring new_passwd; + uchar new_p16[16]; + uchar new_nt_p16[16]; + char *p; + struct smb_passwd *smb_pwent; + FILE *fp; + BOOL valid_old_pwd = False; + BOOL got_valid_nt_entry = False; + long seekpos; + int pwfd; + char ascii_p16[66]; + char c; + int ret, i, err, writelen; + int lockfd = -1; + char *pfile = SMB_PASSWD_FILE; + char readbuf[16 * 1024]; + + setup_logging(argv[0],True); + + charset_initialise(); + +#ifndef DEBUG_PASSWORD + /* Check the effective uid */ + if (geteuid() != 0) { + fprintf(stderr, "%s: Must be setuid root.\n", argv[0]); + exit(1); + } +#endif + + /* Get the real uid */ + real_uid = getuid(); + + /* Deal with usage problems */ + if (real_uid == 0) { + /* As root we can change anothers password. */ + if (argc != 1 && argc != 2) + usage(argv[0]); + } else if (argc != 1) + usage(argv[0]); + + + if (real_uid == 0 && argc == 2) { + /* If we are root we can change anothers password. */ + strncpy(user_name, argv[1], sizeof(user_name) - 1); + user_name[sizeof(user_name) - 1] = '\0'; + pwd = getpwnam(user_name); + } else { + pwd = getpwuid(real_uid); + } + + if (pwd == 0) { + fprintf(stderr, "%s: Unable to get UNIX password entry for user.\n", argv[0]); + exit(1); + } + /* If we are root we don't ask for the old password. */ + old_passwd[0] = '\0'; + if (real_uid != 0) { + p = getpass("Old SMB password:"); + strncpy(old_passwd, p, sizeof(fstring)); + old_passwd[sizeof(fstring)-1] = '\0'; + } + new_passwd[0] = '\0'; + p = getpass("New SMB password:"); + strncpy(new_passwd, p, sizeof(fstring)); + new_passwd[sizeof(fstring)-1] = '\0'; + p = getpass("Retype new SMB password:"); + if (strcmp(p, new_passwd)) { + fprintf(stderr, "%s: Mismatch - password unchanged.\n", argv[0]); + exit(1); + } + + if (new_passwd[0] == '\0') { + printf("Password not set\n"); + exit(0); + } + + /* Calculate the MD4 hash (NT compatible) of the old and new passwords */ + memset(old_nt_p16, '\0', 16); + E_md4hash((uchar *)old_passwd, old_nt_p16); + + memset(new_nt_p16, '\0', 16); + E_md4hash((uchar *) new_passwd, new_nt_p16); + + /* Mangle the passwords into Lanman format */ + old_passwd[14] = '\0'; + strupper(old_passwd); + new_passwd[14] = '\0'; + strupper(new_passwd); + + /* + * Calculate the SMB (lanman) hash functions of both old and new passwords. + */ + + memset(old_p16, '\0', 16); + E_P16((uchar *) old_passwd, old_p16); + + memset(new_p16, '\0', 16); + E_P16((uchar *) new_passwd, new_p16); + + /* + * Open the smbpaswd file XXXX - we need to parse smb.conf to get the + * filename + */ + if ((fp = fopen(pfile, "r+")) == NULL) { + err = errno; + fprintf(stderr, "%s: Failed to open password file %s.\n", + argv[0], pfile); + errno = err; + perror(argv[0]); + exit(err); + } + /* Set read buffer to 16k for effiecient reads */ + setvbuf(fp, readbuf, _IOFBF, sizeof(readbuf)); + + /* make sure it is only rw by the owner */ + chmod(pfile, 0600); + + /* Lock the smbpasswd file for write. */ + if ((lockfd = pw_file_lock(pfile, F_WRLCK, 5)) < 0) { + err = errno; + fprintf(stderr, "%s: Failed to lock password file %s.\n", + argv[0], pfile); + fclose(fp); + errno = err; + perror(argv[0]); + exit(err); + } + /* Get the smb passwd entry for this user */ + smb_pwent = _my_get_smbpwnam(fp, pwd->pw_name, &valid_old_pwd, + &got_valid_nt_entry, &seekpos); + if (smb_pwent == NULL) { + fprintf(stderr, "%s: Failed to find entry for user %s in file %s.\n", + argv[0], pwd->pw_name, pfile); + fclose(fp); + pw_file_unlock(lockfd); + exit(1); + } + /* If we are root we don't need to check the old password. */ + if (real_uid != 0) { + if ((valid_old_pwd == False) || (smb_pwent->smb_passwd == NULL)) { + fprintf(stderr, "%s: User %s is disabled, plase contact your administrator to enable it.\n", argv[0], pwd->pw_name); + fclose(fp); + pw_file_unlock(lockfd); + exit(1); + } + /* Check the old Lanman password */ + if (memcmp(old_p16, smb_pwent->smb_passwd, 16)) { + fprintf(stderr, "%s: Couldn't change password.\n", argv[0]); + fclose(fp); + pw_file_unlock(lockfd); + exit(1); + } + /* Check the NT password if it exists */ + if (smb_pwent->smb_nt_passwd != NULL) { + if (memcmp(old_nt_p16, smb_pwent->smb_nt_passwd, 16)) { + fprintf(stderr, "%s: Couldn't change password.\n", argv[0]); + fclose(fp); + pw_file_unlock(lockfd); + exit(1); + } + } + } + /* + * If we get here either we were root or the old password checked out + * ok. + */ + /* Create the 32 byte representation of the new p16 */ + for (i = 0; i < 16; i++) { + sprintf(&ascii_p16[i * 2], "%02X", (uchar) new_p16[i]); + } + if(got_valid_nt_entry) { + /* Add on the NT md4 hash */ + ascii_p16[32] = ':'; + for (i = 0; i < 16; i++) { + sprintf(&ascii_p16[(i * 2)+33], "%02X", (uchar) new_nt_p16[i]); + } + } + /* + * Do an atomic write into the file at the position defined by + * seekpos. + */ + pwfd = fileno(fp); + ret = lseek(pwfd, seekpos - 1, SEEK_SET); + if (ret != seekpos - 1) { + err = errno; + fprintf(stderr, "%s: seek fail on file %s.\n", + argv[0], pfile); + fclose(fp); + errno = err; + perror(argv[0]); + pw_file_unlock(lockfd); + exit(1); + } + /* Sanity check - ensure the character is a ':' */ + if (read(pwfd, &c, 1) != 1) { + err = errno; + fprintf(stderr, "%s: read fail on file %s.\n", + argv[0], pfile); + fclose(fp); + errno = err; + perror(argv[0]); + pw_file_unlock(lockfd); + exit(1); + } + if (c != ':') { + fprintf(stderr, "%s: sanity check on passwd file %s failed.\n", + argv[0], pfile); + fclose(fp); + pw_file_unlock(lockfd); + exit(1); + } + writelen = (got_valid_nt_entry) ? 65 : 32; + if (write(pwfd, ascii_p16, writelen) != writelen) { + err = errno; + fprintf(stderr, "%s: write fail in file %s.\n", + argv[0], pfile); + fclose(fp); + errno = err; + perror(argv[0]); + pw_file_unlock(lockfd); + exit(err); + } + fclose(fp); + pw_file_unlock(lockfd); + printf("Password changed\n"); + return 0; +} + +#else + +#include "includes.h" + +int +main(int argc, char **argv) +{ + printf("smb password encryption not selected in Makefile\n"); + return 0; +} +#endif diff --git a/source3/utils/status.c b/source3/utils/status.c new file mode 100644 index 0000000000..ed0ae53211 --- /dev/null +++ b/source3/utils/status.c @@ -0,0 +1,258 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + status reporting + Copyright (C) Andrew Tridgell 1994-1995 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + * This program reports current SMB connections + */ + +#ifdef SYSLOG +#undef SYSLOG +#endif + +#include "includes.h" +#include "loadparm.h" + +struct connect_record crec; +extern int DEBUGLEVEL; +extern FILE *dbf; + +static pstring Ucrit_username = ""; /* added by OH */ +int Ucrit_pid[100]; /* Ugly !!! */ /* added by OH */ +int Ucrit_MaxPid=0; /* added by OH */ +unsigned int Ucrit_IsActive = 0; /* added by OH */ +void Ucrit_addUsername(pstring username); /* added by OH */ +unsigned int Ucrit_checkUsername(pstring username); /* added by OH */ +void Ucrit_addPid(int pid); /* added by OH */ +unsigned int Ucrit_checkPid(int pid); /* added by OH */ + +int main(int argc, char *argv[]) +{ + FILE *f; + pstring fname; + int uid, c, n; + static pstring servicesf = CONFIGFILE; + extern char *optarg; + int verbose = 0; + void *dir; + char *s; + BOOL firstopen=True; + BOOL processes_only=False; + int last_pid=0; + + setup_logging(argv[0],True); + + charset_initialise(); + + DEBUGLEVEL = 0; + dbf = fopen("/dev/null","w"); + + if (getuid() != geteuid()) { + printf("smbstatus should not be run setuid\n"); + return(1); + } + + while ((c = getopt(argc, argv, "pdsu:")) != EOF) { + switch (c) { + case 'd': + verbose = 1; + break; + case 'p': + processes_only = 1; + break; + case 's': + strcpy(servicesf, optarg); + break; + case 'u': /* added by OH */ + Ucrit_addUsername(optarg); /* added by OH */ + break; + default: + fprintf(stderr, "Usage: %s [-d] [-p] [-s configfile] [-u username]\n", *argv); /* changed by OH */ + return (-1); + } + } + + + + if (!lp_load(servicesf,False)) { + fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf); + return (-1); + } + + if (verbose) { + printf("using configfile = %s\n", servicesf); + printf("lockdir = %s\n", *lp_lockdir() ? lp_lockdir() : "NULL"); + } + + strcpy(fname,lp_lockdir()); + standard_sub_basic(fname); + trim_string(fname,"","/"); + strcat(fname,"/STATUS..LCK"); + + f = fopen(fname,"r"); + if (!f) { + printf("Couldn't open status file %s\n",fname); + if (!lp_status(-1)) + printf("You need to have status=yes in your smb config file\n"); + return(0); + } + + uid = getuid(); + + if (!processes_only) { + printf("\nSamba version %s\n",VERSION); + + printf("Service uid gid pid machine\n"); + printf("----------------------------------------------\n"); + } + + while (!feof(f)) + { + if (fread(&crec,sizeof(crec),1,f) != 1) + break; + if ( crec.magic == 0x280267 && process_exists(crec.pid) + && Ucrit_checkUsername(uidtoname(crec.uid)) /* added by OH */ + ) + { + Ucrit_addPid(crec.pid); /* added by OH */ + if (processes_only) { + if (last_pid != crec.pid) + printf("%d\n",crec.pid); + last_pid = crec.pid; /* XXXX we can still get repeats, have to + add a sort at some time */ + } + else + printf("%-10.10s %-8s %-8s %5d %-8s (%s) %s", + crec.name,uidtoname(crec.uid),gidtoname(crec.gid),crec.pid, + crec.machine,crec.addr, + asctime(LocalTime(&crec.start,GMT_TO_LOCAL))); + } + } + fclose(f); + + if (processes_only) exit(0); + + printf("\n"); + + dir = opendir(lp_lockdir()); + if (!dir) return(0); + while ((s=readdirname(dir))) { + char buf[16]; + int pid,mode; + time_t t; + int fd; + pstring lname; + int dev,inode; + + if (sscanf(s,"share.%d.%d",&dev,&inode)!=2) continue; + + strcpy(lname,lp_lockdir()); + trim_string(lname,NULL,"/"); + strcat(lname,"/"); + strcat(lname,s); + + fd = open(lname,O_RDONLY,0); + if (fd < 0) continue; + if (read(fd,buf,16) != 16) continue; + n = read(fd,fname,sizeof(fname)); + fname[MAX(n,0)]=0; + close(fd); + + t = IVAL(buf,0); + mode = IVAL(buf,4); + pid = IVAL(buf,8); + + if ( !Ucrit_checkPid(pid) ) /* added by OH */ + continue; + + if (IVAL(buf,12) != LOCKING_VERSION || !process_exists(pid)) { + if (unlink(lname)==0) + printf("Deleted stale share file %s\n",s); + continue; + } + + fname[sizeof(fname)-1] = 0; + + if (firstopen) { + firstopen=False; + printf("Locked files:\n"); + printf("Pid DenyMode R/W Name\n"); + printf("------------------------------\n"); + } + + + printf("%-5d ",pid); + switch ((mode>>4)&0xF) + { + case DENY_NONE: printf("DENY_NONE "); break; + case DENY_ALL: printf("DENY_ALL "); break; + case DENY_DOS: printf("DENY_DOS "); break; + case DENY_READ: printf("DENY_READ "); break; + case DENY_WRITE:printf("DENY_WRITE "); break; + } + switch (mode&0xF) + { + case 0: printf("RDONLY "); break; + case 1: printf("WRONLY "); break; + case 2: printf("RDWR "); break; + } + printf(" %s %s",fname,asctime(LocalTime(&t,GMT_TO_LOCAL))); + } + closedir(dir); + + if (firstopen) + printf("No locked files\n"); + + return (0); +} + +/* added by OH */ +void Ucrit_addUsername(pstring username) +{ + strcpy(Ucrit_username, username); + if(strlen(Ucrit_username) > 0) + Ucrit_IsActive = 1; +} + +unsigned int Ucrit_checkUsername(pstring username) +{ + if ( !Ucrit_IsActive) return 1; + if (strcmp(Ucrit_username,username) ==0) return 1; + return 0; +} + +void Ucrit_addPid(int pid) +{ + int i; + if ( !Ucrit_IsActive) return; + for (i=0;i 8) { + printf("WARNING: You have some share names that are longer than 8 chars\n"); + printf("These may give errors while browsing or may not be accessible\nto some older clients\n"); + break; + } + + if (argc < 4) + { + printf("Press enter to see a dump of your service definitions\n"); + fflush(stdout); + getc(stdin); + lp_dump(); + } + + if (argc == 4) + { + struct from_host f; + f.name = argv[2]; + f.addr = argv[3]; + + /* this is totally ugly, a real `quick' hack */ + for (s=0;s<1000;s++) + if (VALID_SNUM(s)) + { + if (allow_access(lp_hostsdeny(s),lp_hostsallow(s),&f)) + { + printf("Allow connection from %s (%s) to %s\n", + f.name,f.addr,lp_servicename(s)); + } + else + { + printf("Deny connection from %s (%s) to %s\n", + f.name,f.addr,lp_servicename(s)); + } + } + } + return(0); +} + + diff --git a/source3/utils/testprns.c b/source3/utils/testprns.c new file mode 100644 index 0000000000..89c615898d --- /dev/null +++ b/source3/utils/testprns.c @@ -0,0 +1,72 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + test printer setup + Copyright (C) Karl Auer 1993, 1994 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + * Testbed for pcap.c + * + * This module simply checks a given printer name against the compiled-in + * printcap file. + * + * The operation is performed with DEBUGLEVEL at 3. + * + * Useful for a quick check of a printcap file. + * + */ + +#include "includes.h" +#include "smb.h" +#include "pcap.h" + +/* these live in util.c */ +extern FILE *dbf; +extern int DEBUGLEVEL; + +int main(int argc, char *argv[]) +{ + char *pszTemp; + + setup_logging(argv[0],True); + + charset_initialise(); + + if (argc < 2 || argc > 3) + printf("Usage: testprns printername [printcapfile]\n"); + else + { + dbf = fopen("test.log", "w"); + if (dbf == NULL) + printf("Unable to open logfile.\n"); + else + { + DEBUGLEVEL = 3; + pszTemp = (argc < 3) ? PRINTCAP_NAME : argv[2]; + printf("Looking for printer %s in printcap file %s\n", + argv[1], pszTemp); + if (!pcap_printername_ok(argv[1], pszTemp)) + printf("Printer name %s is not valid.\n", argv[1]); + else + printf("Printer name %s is valid.\n", argv[1]); + fclose(dbf); + } + } + return (0); +} + -- cgit