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

📄 pdb_smbpasswd.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
		DEBUG(0, ("del_smbfilepwd_entry: unable to open file %s.\n", pfile));		return False;	}	/*	 * Create the replacement password file.	 */	if((fp_write = startsmbfilepwent(pfile2, PWF_CREATE, &pfile2_lockdepth)) == NULL) {		DEBUG(0, ("del_smbfilepwd_entry: unable to open file %s.\n", pfile));		endsmbfilepwent(fp, &smbpasswd_state->pw_file_lock_depth);		return False;	}	/*	 * Scan the file, a line at a time and check if the name matches.	 */	while ((pwd = getsmbfilepwent(smbpasswd_state, fp)) != NULL) {		char *new_entry;		size_t new_entry_length;		if (strequal(name, pwd->smb_name)) {			DEBUG(10, ("add_smbfilepwd_entry: found entry with name %s - deleting it.\n", name));			continue;		}		/*		 * We need to copy the entry out into the second file.		 */		if((new_entry = format_new_smbpasswd_entry(pwd)) == NULL) {			DEBUG(0, ("del_smbfilepwd_entry(malloc): Failed to copy entry for user %s to file %s. \Error was %s\n", pwd->smb_name, pfile2, strerror(errno)));			unlink(pfile2);			endsmbfilepwent(fp, &smbpasswd_state->pw_file_lock_depth);			endsmbfilepwent(fp_write, &pfile2_lockdepth);			return False;		}		new_entry_length = strlen(new_entry);		if(fwrite(new_entry, 1, new_entry_length, fp_write) != new_entry_length) {			DEBUG(0, ("del_smbfilepwd_entry(write): Failed to copy entry for user %s to file %s. \Error was %s\n", pwd->smb_name, pfile2, strerror(errno)));			unlink(pfile2);			endsmbfilepwent(fp, &smbpasswd_state->pw_file_lock_depth);			endsmbfilepwent(fp_write, &pfile2_lockdepth);			free(new_entry);			return False;		}		free(new_entry);	}	/*	 * Ensure pfile2 is flushed before rename.	 */	if(fflush(fp_write) != 0) {		DEBUG(0, ("del_smbfilepwd_entry: Failed to flush file %s. Error was %s\n", pfile2, strerror(errno)));		endsmbfilepwent(fp, &smbpasswd_state->pw_file_lock_depth);		endsmbfilepwent(fp_write,&pfile2_lockdepth);		return False;	}	/*	 * Do an atomic rename - then release the locks.	 */	if(rename(pfile2,pfile) != 0) {		unlink(pfile2);	}  	endsmbfilepwent(fp, &smbpasswd_state->pw_file_lock_depth);	endsmbfilepwent(fp_write,&pfile2_lockdepth);	return True;}/********************************************************************* Create a smb_passwd struct from a SAM_ACCOUNT. We will not allocate any new memory.  The smb_passwd struct should only stay around as long as the SAM_ACCOUNT does. ********************************************************************/static BOOL build_smb_pass (struct smb_passwd *smb_pw, const SAM_ACCOUNT *sampass){	uint32 rid;	if (sampass == NULL) 		return False;	ZERO_STRUCTP(smb_pw);	if (!IS_SAM_DEFAULT(sampass, PDB_USERSID)) {		rid = pdb_get_user_rid(sampass);				/* If the user specified a RID, make sure its able to be both stored and retreived */		if (rid == DOMAIN_USER_RID_GUEST) {			struct passwd *passwd = getpwnam_alloc(lp_guestaccount());			if (!passwd) {				DEBUG(0, ("Could not find gest account via getpwnam()! (%s)\n", lp_guestaccount()));				return False;			}			smb_pw->smb_userid=passwd->pw_uid;			passwd_free(&passwd);		} else if (algorithmic_pdb_rid_is_user(rid)) {			smb_pw->smb_userid=algorithmic_pdb_user_rid_to_uid(rid);		} else {			DEBUG(0,("build_sam_pass: Failing attempt to store user with non-uid based user RID. \n"));			return False;		}	}	smb_pw->smb_name=(const char*)pdb_get_username(sampass);	smb_pw->smb_passwd=pdb_get_lanman_passwd(sampass);	smb_pw->smb_nt_passwd=pdb_get_nt_passwd(sampass);	smb_pw->acct_ctrl=pdb_get_acct_ctrl(sampass);	smb_pw->pass_last_set_time=pdb_get_pass_last_set_time(sampass);	return True;}	/********************************************************************* Create a SAM_ACCOUNT from a smb_passwd struct ********************************************************************/static BOOL build_sam_account(struct smbpasswd_privates *smbpasswd_state, 			      SAM_ACCOUNT *sam_pass, const struct smb_passwd *pw_buf){	struct passwd *pwfile;		if (sam_pass==NULL) {		DEBUG(5,("build_sam_account: SAM_ACCOUNT is NULL\n"));		return False;	}	/* verify the user account exists */				if ( !(pwfile = getpwnam_alloc(pw_buf->smb_name)) ) {		DEBUG(0,("build_sam_account: smbpasswd database is corrupt!  username %s with uid "		"%u is not in unix passwd database!\n", pw_buf->smb_name, pw_buf->smb_userid));			return False;	}		if (!NT_STATUS_IS_OK(pdb_fill_sam_pw(sam_pass, pwfile)))		return False;			passwd_free(&pwfile);	/* set remaining fields */			pdb_set_nt_passwd (sam_pass, pw_buf->smb_nt_passwd, PDB_SET);	pdb_set_lanman_passwd (sam_pass, pw_buf->smb_passwd, PDB_SET);				pdb_set_acct_ctrl (sam_pass, pw_buf->acct_ctrl, PDB_SET);	pdb_set_pass_last_set_time (sam_pass, pw_buf->pass_last_set_time, PDB_SET);	pdb_set_pass_can_change_time (sam_pass, pw_buf->pass_last_set_time, PDB_SET);		return True;}/***************************************************************** Functions to be implemented by the new passdb API  ****************************************************************/static NTSTATUS smbpasswd_setsampwent (struct pdb_methods *my_methods, BOOL update, uint16 acb_mask){	struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;		smbpasswd_state->pw_file = startsmbfilepwent(smbpasswd_state->smbpasswd_file, 						       update ? PWF_UPDATE : PWF_READ, 						       &(smbpasswd_state->pw_file_lock_depth));				   	/* did we fail?  Should we try to create it? */	if (!smbpasswd_state->pw_file && update && errno == ENOENT) {		FILE *fp;		/* slprintf(msg_str,msg_str_len-1,		   "smbpasswd file did not exist - attempting to create it.\n"); */		DEBUG(0,("smbpasswd file did not exist - attempting to create it.\n"));		fp = sys_fopen(smbpasswd_state->smbpasswd_file, "w");		if (fp) {			fprintf(fp, "# Samba SMB password file\n");			fclose(fp);		}				smbpasswd_state->pw_file = startsmbfilepwent(smbpasswd_state->smbpasswd_file, 							     update ? PWF_UPDATE : PWF_READ, 							     &(smbpasswd_state->pw_file_lock_depth));	}		if (smbpasswd_state->pw_file != NULL)		return NT_STATUS_OK;	else		return NT_STATUS_UNSUCCESSFUL;  }static void smbpasswd_endsampwent (struct pdb_methods *my_methods){	struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;	endsmbfilepwent(smbpasswd_state->pw_file, &(smbpasswd_state->pw_file_lock_depth));} /***************************************************************** ****************************************************************/static NTSTATUS smbpasswd_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user){	NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;	struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;	struct smb_passwd *pw_buf=NULL;	BOOL done = False;	DEBUG(5,("pdb_getsampwent\n"));	if (user==NULL) {		DEBUG(5,("pdb_getsampwent (smbpasswd): user is NULL\n"));#if 0		smb_panic("NULL pointer passed to getsampwent (smbpasswd)\n");#endif		return nt_status;	}	while (!done) {		/* do we have an entry? */		pw_buf = getsmbfilepwent(smbpasswd_state, smbpasswd_state->pw_file);		if (pw_buf == NULL) 			return nt_status;		/* build the SAM_ACCOUNT entry from the smb_passwd struct. 		   We loop in case the user in the pdb does not exist in 		   the local system password file */		if (build_sam_account(smbpasswd_state, user, pw_buf))			done = True;	}	DEBUG(5,("getsampwent (smbpasswd): done\n"));	/* success */	return NT_STATUS_OK;}/**************************************************************** Search smbpasswd file by iterating over the entries.  Do not call getpwnam() for unix account information until we have found the correct entry ***************************************************************/static NTSTATUS smbpasswd_getsampwnam(struct pdb_methods *my_methods, 				  SAM_ACCOUNT *sam_acct, const char *username){	NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;	struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;	struct smb_passwd *smb_pw;	void *fp = NULL;	DEBUG(10, ("getsampwnam (smbpasswd): search by name: %s\n", username));	/* startsmbfilepwent() is used here as we don't want to lookup	   the UNIX account in the local system password file until	   we have a match.  */	fp = startsmbfilepwent(smbpasswd_state->smbpasswd_file, PWF_READ, &(smbpasswd_state->pw_file_lock_depth));	if (fp == NULL) {		DEBUG(0, ("Unable to open passdb database.\n"));		return nt_status;	}	while ( ((smb_pw=getsmbfilepwent(smbpasswd_state, fp)) != NULL)&& (!strequal(smb_pw->smb_name, username)) )		/* do nothing....another loop */ ;		endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));	/* did we locate the username in smbpasswd  */	if (smb_pw == NULL)		return nt_status;		DEBUG(10, ("getsampwnam (smbpasswd): found by name: %s\n", smb_pw->smb_name));	if (!sam_acct) {		DEBUG(10,("getsampwnam (smbpasswd): SAM_ACCOUNT is NULL\n"));#if 0		smb_panic("NULL pointer passed to pdb_getsampwnam\n");#endif		return nt_status;	}			/* now build the SAM_ACCOUNT */	if (!build_sam_account(smbpasswd_state, sam_acct, smb_pw))		return nt_status;	/* success */	return NT_STATUS_OK;}static NTSTATUS smbpasswd_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT *sam_acct, const DOM_SID *sid){	NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;	struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;	struct smb_passwd *smb_pw;	void *fp = NULL;	fstring sid_str;	uint32 rid;		DEBUG(10, ("smbpasswd_getsampwrid: search by sid: %s\n", sid_to_string(sid_str, sid)));	if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))		return NT_STATUS_UNSUCCESSFUL;	/* More special case 'guest account' hacks... */	if (rid == DOMAIN_USER_RID_GUEST) {		const char *guest_account = lp_guestaccount();		if (!(guest_account && *guest_account)) {			DEBUG(1, ("Guest account not specfied!\n"));			return nt_status;		}		return smbpasswd_getsampwnam(my_methods, sam_acct, guest_account);	}	/* Open the sam password file - not for update. */	fp = startsmbfilepwent(smbpasswd_state->smbpasswd_file, PWF_READ, &(smbpasswd_state->pw_file_lock_depth));	if (fp == NULL) {		DEBUG(0, ("Unable to open passdb database.\n"));		return nt_status;	}	while ( ((smb_pw=getsmbfilepwent(smbpasswd_state, fp)) != NULL) && (algorithmic_pdb_uid_to_user_rid(smb_pw->smb_userid) != rid) )      		/* do nothing */ ;	endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));	/* did we locate the username in smbpasswd  */	if (smb_pw == NULL)		return nt_status;		DEBUG(10, ("getsampwrid (smbpasswd): found by name: %s\n", smb_pw->smb_name));			if (!sam_acct) {		DEBUG(10,("getsampwrid: (smbpasswd) SAM_ACCOUNT is NULL\n"));#if 0		smb_panic("NULL pointer passed to pdb_getsampwrid\n");#endif		return nt_status;	}	/* now build the SAM_ACCOUNT */	if (!build_sam_account (smbpasswd_state, sam_acct, smb_pw))		return nt_status;	/* build_sam_account might change the SID on us, if the name was for the guest account */	if (NT_STATUS_IS_OK(nt_status) && !sid_equal(pdb_get_user_sid(sam_acct), sid)) {		fstring sid_string1, sid_string2;		DEBUG(1, ("looking for user with sid %s instead returned %s for account %s!?!\n",			  sid_to_string(sid_string1, sid), sid_to_string(sid_string2, pdb_get_user_sid(sam_acct)), pdb_get_username(sam_acct)));		return NT_STATUS_NO_SUCH_USER;	}	/* success */	return NT_STATUS_OK;}static NTSTATUS smbpasswd_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT *sampass){	struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;	struct smb_passwd smb_pw;		/* convert the SAM_ACCOUNT */	if (!build_smb_pass(&smb_pw, sampass)) {		return NT_STATUS_UNSUCCESSFUL;	}		/* add the entry */	if(!add_smbfilepwd_entry(smbpasswd_state, &smb_pw)) {		return NT_STATUS_UNSUCCESSFUL;	}		return NT_STATUS_OK;}static NTSTATUS smbpasswd_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT *sampass){	struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;	struct smb_passwd smb_pw;		/* convert the SAM_ACCOUNT */	if (!build_smb_pass(&smb_pw, sampass)) {		DEBUG(0, ("smbpasswd_update_sam_account: build_smb_pass failed!\n"));		return NT_STATUS_UNSUCCESSFUL;	}		/* update the entry */	if(!mod_smbfilepwd_entry(smbpasswd_state, &smb_pw)) {		DEBUG(0, ("smbpasswd_update_sam_account: mod_smbfilepwd_entry failed!\n"));		return NT_STATUS_UNSUCCESSFUL;	}		return NT_STATUS_OK;}static NTSTATUS smbpasswd_delete_sam_account (struct pdb_methods *my_methods, SAM_ACCOUNT *sampass){	struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;	const char *username = pdb_get_username(sampass);	if (del_smbfilepwd_entry(smbpasswd_state, username))		return NT_STATUS_OK;	return NT_STATUS_UNSUCCESSFUL;}static NTSTATUS smbpasswd_rename_sam_account (struct pdb_methods *my_methods, 					      SAM_ACCOUNT *old_acct,					      const char *newname){	pstring rename_script;	SAM_ACCOUNT *new_acct = NULL;	BOOL interim_account = False;	NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;	if (!*(lp_renameuser_script()))		goto done;	if (!pdb_copy_sam_account(old_acct, &new_acct) ||	    !pdb_set_username(new_acct, newname, PDB_CHANGED))		goto done;	ret = smbpasswd_add_sam_account(my_methods, new_acct);	if (!NT_STATUS_IS_OK(ret))		goto done;	interim_account = True;	/* rename the posix user */	pstrcpy(rename_script, lp_renameuser_script());	if (*rename_script) {	        int rename_ret;		pstring_sub(rename_script, "%unew", newname);		pstring_sub(rename_script, "%uold", 			    pdb_get_username(old_acct));		rename_ret = smbrun(rename_script, NULL);		DEBUG(rename_ret ? 0 : 3,("Running the command `%s' gave %d\n", rename_script, rename_ret));		if (rename_ret) 			goto done;         } else {		goto done;	}	smbpasswd_delete_sam_account(my_methods, old_acct);	interim_account = False;done:		/* cleanup */	if (interim_account)		smbpasswd_delete_sam_account(my_methods, new_acct);	if (new_acct)		pdb_free_sam(&new_acct);		return (ret);	}static void free_private_data(void **vp) {	struct smbpasswd_privates **privates = (struct smbpasswd_privates**)vp;		endsmbfilepwent((*privates)->pw_file, &((*privates)->pw_file_lock_depth));		*privates = NULL;	/* No need to free any further, as it is talloc()ed */}static NTSTATUS pdb_init_smbpasswd(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location){	NTSTATUS nt_status;	struct smbpasswd_privates *privates;	if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {		return nt_status;	}	(*pdb_method)->name = "smbpasswd";	(*pdb_method)->setsampwent = smbpasswd_setsampwent;	(*pdb_method)->endsampwent = smbpasswd_endsampwent;	(*pdb_method)->getsampwent = smbpasswd_getsampwent;	(*pdb_method)->getsampwnam = smbpasswd_getsampwnam;	(*pdb_method)->getsampwsid = smbpasswd_getsampwsid;	(*pdb_method)->add_sam_account = smbpasswd_add_sam_account;	(*pdb_method)->update_sam_account = smbpasswd_update_sam_account;	(*pdb_method)->delete_sam_account = smbpasswd_delete_sam_account;	(*pdb_method)->rename_sam_account = smbpasswd_rename_sam_account;	/* Setup private data and free function */	privates = TALLOC_ZERO_P(pdb_context->mem_ctx, struct smbpasswd_privates);	if (!privates) {		DEBUG(0, ("talloc() failed for smbpasswd private_data!\n"));		return NT_STATUS_NO_MEMORY;	}	/* Store some config details */	if (location) {		privates->smbpasswd_file = talloc_strdup(pdb_context->mem_ctx, location);	} else {		privates->smbpasswd_file = talloc_strdup(pdb_context->mem_ctx, lp_smb_passwd_file());	}		if (!privates->smbpasswd_file) {		DEBUG(0, ("talloc_strdp() failed for storing smbpasswd location!\n"));		return NT_STATUS_NO_MEMORY;	}	(*pdb_method)->private_data = privates;	(*pdb_method)->free_private_data = free_private_data;	return NT_STATUS_OK;}NTSTATUS pdb_smbpasswd_init(void) {	return smb_register_passdb(PASSDB_INTERFACE_VERSION, "smbpasswd", pdb_init_smbpasswd);}

⌨️ 快捷键说明

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