⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pdb_smbpasswd.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
		}		return pw_buf;	}	DEBUG(5,("getsmbfilepwent: end of file reached.\n"));	return NULL;}/************************************************************************ Create a new smbpasswd entry - malloced space returned.*************************************************************************/static char *format_new_smbpasswd_entry(const struct smb_passwd *newpwd){	int new_entry_length;	char *new_entry;	char *p;	new_entry_length = strlen(newpwd->smb_name) + 1 + 15 + 1 + 32 + 1 + 32 + 1 + 				NEW_PW_FORMAT_SPACE_PADDED_LEN + 1 + 13 + 2;	if((new_entry = (char *)SMB_MALLOC( new_entry_length )) == NULL) {		DEBUG(0, ("format_new_smbpasswd_entry: Malloc failed adding entry for user %s.\n",			newpwd->smb_name ));		return NULL;	}	slprintf(new_entry, new_entry_length - 1, "%s:%u:", newpwd->smb_name, (unsigned)newpwd->smb_userid);	p = new_entry+strlen(new_entry);	pdb_sethexpwd(p, newpwd->smb_passwd, newpwd->acct_ctrl);	p+=strlen(p);	*p = ':';	p++;	pdb_sethexpwd(p, newpwd->smb_nt_passwd, newpwd->acct_ctrl);	p+=strlen(p);	*p = ':';	p++;	/* Add the account encoding and the last change time. */	slprintf((char *)p, new_entry_length - 1 - (p - new_entry),  "%s:LCT-%08X:\n",		pdb_encode_acct_ctrl(newpwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN),		(uint32)newpwd->pass_last_set_time);	return new_entry;}/************************************************************************ Routine to add an entry to the smbpasswd file.*************************************************************************/static BOOL add_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, struct smb_passwd *newpwd){	const char *pfile = smbpasswd_state->smbpasswd_file;	struct smb_passwd *pwd = NULL;	FILE *fp = NULL;	int wr_len;	int fd;	size_t new_entry_length;	char *new_entry;	SMB_OFF_T offpos;	uint32 max_found_uid = 0; 	/* Open the smbpassword file - for update. */	fp = startsmbfilepwent(pfile, PWF_UPDATE, &smbpasswd_state->pw_file_lock_depth);	if (fp == NULL && errno == ENOENT) {		/* Try again - create. */		fp = startsmbfilepwent(pfile, PWF_CREATE, &smbpasswd_state->pw_file_lock_depth);	}	if (fp == NULL) {		DEBUG(0, ("add_smbfilepwd_entry: unable to open file.\n"));		return False;	}	/*	 * Scan the file, a line at a time and check if the name matches.	 */	while ((pwd = getsmbfilepwent(smbpasswd_state, fp)) != NULL) {		if (strequal(newpwd->smb_name, pwd->smb_name)) {			DEBUG(0, ("add_smbfilepwd_entry: entry with name %s already exists\n", pwd->smb_name));			endsmbfilepwent(fp, &smbpasswd_state->pw_file_lock_depth);			return False;		}    		/* Look for a free uid for use in non-unix accounts */		if (pwd->smb_userid > max_found_uid) {			max_found_uid = pwd->smb_userid;		}	}	/* Ok - entry doesn't exist. We can add it */	/* Create a new smb passwd entry and set it to the given password. */	/* 	 * The add user write needs to be atomic - so get the fd from 	 * the fp and do a raw write() call.	 */	fd = fileno(fp);	if((offpos = sys_lseek(fd, 0, SEEK_END)) == -1) {		DEBUG(0, ("add_smbfilepwd_entry(sys_lseek): Failed to add entry for user %s to file %s. \Error was %s\n", newpwd->smb_name, pfile, strerror(errno)));		endsmbfilepwent(fp, &smbpasswd_state->pw_file_lock_depth);		return False;	}	if((new_entry = format_new_smbpasswd_entry(newpwd)) == NULL) {		DEBUG(0, ("add_smbfilepwd_entry(malloc): Failed to add entry for user %s to file %s. \Error was %s\n", newpwd->smb_name, pfile, strerror(errno)));		endsmbfilepwent(fp, &smbpasswd_state->pw_file_lock_depth);		return False;	}	new_entry_length = strlen(new_entry);#ifdef DEBUG_PASSWORD	DEBUG(100, ("add_smbfilepwd_entry(%d): new_entry_len %d made line |%s|", 			fd, (int)new_entry_length, new_entry));#endif	if ((wr_len = write(fd, new_entry, new_entry_length)) != new_entry_length) {		DEBUG(0, ("add_smbfilepwd_entry(write): %d Failed to add entry for user %s to file %s. \Error was %s\n", wr_len, newpwd->smb_name, pfile, strerror(errno)));		/* Remove the entry we just wrote. */		if(sys_ftruncate(fd, offpos) == -1) {			DEBUG(0, ("add_smbfilepwd_entry: ERROR failed to ftruncate file %s. \Error was %s. Password file may be corrupt ! Please examine by hand !\n", 				newpwd->smb_name, strerror(errno)));		}		endsmbfilepwent(fp, &smbpasswd_state->pw_file_lock_depth);		free(new_entry);		return False;	}	free(new_entry);	endsmbfilepwent(fp, &smbpasswd_state->pw_file_lock_depth);	return True;}/************************************************************************ Routine to search the smbpasswd file for an entry matching the username. and then modify its password entry. We can't use the startsmbpwent()/ getsmbpwent()/endsmbpwent() interfaces here as we depend on looking in the actual file to decide how much room we have to write data. override = False, normal override = True, override XXXXXXXX'd out password or NO PASS************************************************************************/static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, const struct smb_passwd* pwd){	/* Static buffers we will return. */	pstring user_name;	char *status;	char linebuf[256];	char readbuf[1024];	int c;	fstring ascii_p16;	fstring encode_bits;	unsigned char *p = NULL;	size_t linebuf_len = 0;	FILE *fp;	int lockfd;	const char *pfile = smbpasswd_state->smbpasswd_file;	BOOL found_entry = False;	BOOL got_pass_last_set_time = False;	SMB_OFF_T pwd_seekpos = 0;	int i;	int wr_len;	int fd;	if (!*pfile) {		DEBUG(0, ("No SMB password file set\n"));		return False;	}	DEBUG(10, ("mod_smbfilepwd_entry: opening file %s\n", pfile));	fp = sys_fopen(pfile, "r+");	if (fp == NULL) {		DEBUG(0, ("mod_smbfilepwd_entry: unable to open file %s\n", pfile));		return False;	}	/* Set a buffer to do more efficient reads */	setvbuf(fp, readbuf, _IOFBF, sizeof(readbuf));	lockfd = fileno(fp);	if (!pw_file_lock(lockfd, F_WRLCK, 5, &smbpasswd_state->pw_file_lock_depth)) {		DEBUG(0, ("mod_smbfilepwd_entry: unable to lock file %s\n", pfile));		fclose(fp);		return False;	}	/* Make sure it is only rw by the owner */	chmod(pfile, 0600);	/* We have a write lock on the file. */	/*	 * Scan the file, a line at a time and check if the name matches.	 */	status = linebuf;	while (status && !feof(fp)) {		pwd_seekpos = sys_ftell(fp);		linebuf[0] = '\0';		status = fgets(linebuf, sizeof(linebuf), fp);		if (status == NULL && ferror(fp)) {			pw_file_unlock(lockfd, &smbpasswd_state->pw_file_lock_depth);			fclose(fp);			return False;		}		/*		 * Check if the string is terminated with a newline - if not		 * then we must keep reading and discard until we get one.		 */		linebuf_len = strlen(linebuf);		if (linebuf[linebuf_len - 1] != '\n') {			c = '\0';			while (!ferror(fp) && !feof(fp)) {				c = fgetc(fp);				if (c == '\n') {					break;				}			}		} else {			linebuf[linebuf_len - 1] = '\0';		}#ifdef DEBUG_PASSWORD		DEBUG(100, ("mod_smbfilepwd_entry: got line |%s|\n", linebuf));#endif		if ((linebuf[0] == 0) && feof(fp)) {			DEBUG(4, ("mod_smbfilepwd_entry: end of file reached\n"));			break;		}		/*		 * The line we have should be of the form :-		 * 		 * username:uid:[32hex bytes]:....other flags presently		 * ignored....		 * 		 * or,		 *		 * username:uid:[32hex bytes]:[32hex bytes]:[attributes]:LCT-XXXXXXXX:...ignored.		 *		 * if Windows NT compatible passwords are also present.		 */		if (linebuf[0] == '#' || linebuf[0] == '\0') {			DEBUG(6, ("mod_smbfilepwd_entry: skipping comment or blank line\n"));			continue;		}		p = (unsigned char *) strchr_m(linebuf, ':');		if (p == NULL) {			DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (no :)\n"));			continue;		}		/*		 * As 256 is shorter than a pstring we don't need to check		 * length here - if this ever changes....		 */		SMB_ASSERT(sizeof(user_name) > sizeof(linebuf));		strncpy(user_name, linebuf, PTR_DIFF(p, linebuf));		user_name[PTR_DIFF(p, linebuf)] = '\0';		if (strequal(user_name, pwd->smb_name)) {			found_entry = True;			break;		}	}	if (!found_entry) {		pw_file_unlock(lockfd, &smbpasswd_state->pw_file_lock_depth);		fclose(fp);		DEBUG(2, ("Cannot update entry for user %s, as they don't exist in the smbpasswd file!\n",			pwd->smb_name));		return False;	}	DEBUG(6, ("mod_smbfilepwd_entry: entry exists for user %s\n", pwd->smb_name));	/* User name matches - get uid and password */	p++; /* Go past ':' */	if (!isdigit(*p)) {		DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry for user %s (uid not number)\n",			pwd->smb_name));		pw_file_unlock(lockfd, &smbpasswd_state->pw_file_lock_depth);		fclose(fp);		return False;	}	while (*p && isdigit(*p)) {		p++;	}	if (*p != ':') {		DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry for user %s (no : after uid)\n",			pwd->smb_name));		pw_file_unlock(lockfd, &smbpasswd_state->pw_file_lock_depth);		fclose(fp);		return False;	}	/*	 * Now get the password value - this should be 32 hex digits	 * which are the ascii representations of a 16 byte string.	 * Get two at a time and put them into the password.	 */	p++;	/* Record exact password position */	pwd_seekpos += PTR_DIFF(p, linebuf);	if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {		DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry for user %s (passwd too short)\n",			pwd->smb_name));		pw_file_unlock(lockfd,&smbpasswd_state->pw_file_lock_depth);		fclose(fp);		return (False);	}	if (p[32] != ':') {		DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry for user %s (no terminating :)\n",			pwd->smb_name));		pw_file_unlock(lockfd,&smbpasswd_state->pw_file_lock_depth);		fclose(fp);		return False;	}	/* 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)) {		DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry for user %s (passwd too short)\n",			pwd->smb_name));		pw_file_unlock(lockfd,&smbpasswd_state->pw_file_lock_depth);		fclose(fp);		return (False);	}	if (p[32] != ':') {		DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry for user %s (no terminating :)\n",			pwd->smb_name));		pw_file_unlock(lockfd,&smbpasswd_state->pw_file_lock_depth);		fclose(fp);		return False;	}	/* 	 * Now check if the account info and the password last	 * change time is available.	 */	p += 33; /* Move to the first character of the line after the NT password. */	if (*p == '[') {		i = 0;		encode_bits[i++] = *p++;		while((linebuf_len > PTR_DIFF(p, linebuf)) && (*p != ']')) {			encode_bits[i++] = *p++;		}		encode_bits[i++] = ']';		encode_bits[i++] = '\0';		if(i == NEW_PW_FORMAT_SPACE_PADDED_LEN) {			/*			 * We are using a new format, space padded			 * acct ctrl field. Encode the given acct ctrl			 * bits into it.			 */			fstrcpy(encode_bits, pdb_encode_acct_ctrl(pwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN));		} else {			DEBUG(0,("mod_smbfilepwd_entry:  Using old smbpasswd format for user %s. \This is no longer supported.!\n", pwd->smb_name));			DEBUG(0,("mod_smbfilepwd_entry:  No changes made, failing.!\n"));			pw_file_unlock(lockfd, &smbpasswd_state->pw_file_lock_depth);			fclose(fp);			return False;		}		/* Go past the ']' */		if(linebuf_len > PTR_DIFF(p, linebuf)) {			p++;		}		if((linebuf_len > PTR_DIFF(p, linebuf)) && (*p == ':')) {			p++;			/* We should be pointing at the LCT entry. */			if((linebuf_len > (PTR_DIFF(p, linebuf) + 13)) && (StrnCaseCmp((char *)p, "LCT-", 4) == 0)) {				p += 4;				for(i = 0; i < 8; i++) {					if(p[i] == '\0' || !isxdigit(p[i])) {						break;					}				}				if(i == 8) {					/*					 * p points at 8 characters of hex digits -					 * read into a time_t as the seconds since					 * 1970 that the password was last changed.					 */					got_pass_last_set_time = True;				} /* i == 8 */			} /* *p && StrnCaseCmp() */		} /* p == ':' */	} /* p == '[' */	/* Entry is correctly formed. */	/* Create the 32 byte representation of the new p16 */	pdb_sethexpwd(ascii_p16, pwd->smb_passwd, pwd->acct_ctrl);	/* Add on the NT md4 hash */	ascii_p16[32] = ':';	wr_len = 66;	pdb_sethexpwd(ascii_p16+33, pwd->smb_nt_passwd, pwd->acct_ctrl);	ascii_p16[65] = ':';	ascii_p16[66] = '\0'; /* null-terminate the string so that strlen works */	/* Add on the account info bits and the time of last password change. */	if(got_pass_last_set_time) {		slprintf(&ascii_p16[strlen(ascii_p16)], 			sizeof(ascii_p16)-(strlen(ascii_p16)+1),			"%s:LCT-%08X:", 			encode_bits, (uint32)pwd->pass_last_set_time );		wr_len = strlen(ascii_p16);	}#ifdef DEBUG_PASSWORD	DEBUG(100,("mod_smbfilepwd_entry: "));	dump_data(100, ascii_p16, wr_len);#endif	if(wr_len > sizeof(linebuf)) {		DEBUG(0, ("mod_smbfilepwd_entry: line to write (%d) is too long.\n", wr_len+1));		pw_file_unlock(lockfd,&smbpasswd_state->pw_file_lock_depth);		fclose(fp);		return (False);	}	/*	 * Do an atomic write into the file at the position defined by	 * seekpos.	 */	/* The mod user write needs to be atomic - so get the fd from 		the fp and do a raw write() call.	 */	fd = fileno(fp);	if (sys_lseek(fd, pwd_seekpos - 1, SEEK_SET) != pwd_seekpos - 1) {		DEBUG(0, ("mod_smbfilepwd_entry: seek fail on file %s.\n", pfile));		pw_file_unlock(lockfd,&smbpasswd_state->pw_file_lock_depth);		fclose(fp);		return False;	}	/* Sanity check - ensure the areas we are writing are framed by ':' */	if (read(fd, linebuf, wr_len+1) != wr_len+1) {		DEBUG(0, ("mod_smbfilepwd_entry: read fail on file %s.\n", pfile));		pw_file_unlock(lockfd,&smbpasswd_state->pw_file_lock_depth);		fclose(fp);		return False;	}	if ((linebuf[0] != ':') || (linebuf[wr_len] != ':'))	{		DEBUG(0, ("mod_smbfilepwd_entry: check on passwd file %s failed.\n", pfile));		pw_file_unlock(lockfd,&smbpasswd_state->pw_file_lock_depth);		fclose(fp);		return False;	} 	if (sys_lseek(fd, pwd_seekpos, SEEK_SET) != pwd_seekpos) {		DEBUG(0, ("mod_smbfilepwd_entry: seek fail on file %s.\n", pfile));		pw_file_unlock(lockfd,&smbpasswd_state->pw_file_lock_depth);		fclose(fp);		return False;	}	if (write(fd, ascii_p16, wr_len) != wr_len) {		DEBUG(0, ("mod_smbfilepwd_entry: write failed in passwd file %s\n", pfile));		pw_file_unlock(lockfd,&smbpasswd_state->pw_file_lock_depth);		fclose(fp);		return False;	}	pw_file_unlock(lockfd,&smbpasswd_state->pw_file_lock_depth);	fclose(fp);	return True;}/************************************************************************ Routine to delete an entry in the smbpasswd file by name.*************************************************************************/static BOOL del_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, const char *name){	const char *pfile = smbpasswd_state->smbpasswd_file;	pstring pfile2;	struct smb_passwd *pwd = NULL;	FILE *fp = NULL;	FILE *fp_write = NULL;	int pfile2_lockdepth = 0;	slprintf(pfile2, sizeof(pfile2)-1, "%s.%u", pfile, (unsigned)sys_getpid() );	/*	 * Open the smbpassword file - for update. It needs to be update	 * as we need any other processes to wait until we have replaced	 * it.	 */	if((fp = startsmbfilepwent(pfile, PWF_UPDATE, &smbpasswd_state->pw_file_lock_depth)) == NULL) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -