Esempio n. 1
0
int smb_update_db( pam_handle_t *pamh, int ctrl, const char *user,  const char *pass_new )
{
	int retval;
	pstring err_str;
	pstring msg_str;

	err_str[0] = '\0';
	msg_str[0] = '\0';

	retval = local_password_change( user, LOCAL_SET_PASSWORD, pass_new,
	                                err_str, sizeof(err_str),
	                                msg_str, sizeof(msg_str) );

	if (!retval) {
		if (*err_str) {
			err_str[PSTRING_LEN-1] = '\0';
			make_remark( pamh, ctrl, PAM_ERROR_MSG, err_str );
		}

		/* FIXME: what value is appropriate here? */
		retval = PAM_AUTHTOK_ERR;
	} else {
		if (*msg_str) {
			msg_str[PSTRING_LEN-1] = '\0';
			make_remark( pamh, ctrl, PAM_TEXT_INFO, msg_str );
		}
		retval = PAM_SUCCESS;
	}

	return retval;      
}
Esempio n. 2
0
/* Helper function for adding a user to the db. */
static int _smb_add_user(pam_handle_t *pamh, unsigned int ctrl,
                         const char *name, struct samu *sampass, bool exist)
{
	char *err_str = NULL;
	char *msg_str = NULL;
	const char *pass = NULL;
	int retval;
	TALLOC_CTX *frame = talloc_stackframe();

	/* Get the authtok; if we don't have one, silently fail. */
	retval = _pam_get_item( pamh, PAM_AUTHTOK, &pass );

	if (retval != PAM_SUCCESS) {
		_log_err(pamh, LOG_ALERT
			, "pam_get_item returned error to pam_sm_authenticate" );
		TALLOC_FREE(frame);
		return PAM_AUTHTOK_RECOVER_ERR;
	}

	/* Add the user to the db if they aren't already there. */
	if (!exist) {
		retval = NT_STATUS_IS_OK(local_password_change(name, LOCAL_ADD_USER|LOCAL_SET_PASSWORD,
					pass, &err_str, &msg_str));
		if (!retval && err_str) {
			make_remark(pamh, ctrl, PAM_ERROR_MSG, err_str );
		} else if (msg_str) {
			make_remark(pamh, ctrl, PAM_TEXT_INFO, msg_str );
		}
		pass = NULL;

		SAFE_FREE(err_str);
		SAFE_FREE(msg_str);
		TALLOC_FREE(frame);
		return PAM_IGNORE;
	} else {
		/* mimick 'update encrypted' as long as the 'no pw req' flag is not set */
		if ( pdb_get_acct_ctrl(sampass) & ~ACB_PWNOTREQ ) {
			retval = NT_STATUS_IS_OK(local_password_change(name, LOCAL_SET_PASSWORD,
					pass, &err_str, &msg_str));
			if (!retval && err_str) {
				make_remark(pamh, ctrl, PAM_ERROR_MSG, err_str );
			} else if (msg_str) {
				make_remark(pamh, ctrl, PAM_TEXT_INFO, msg_str );
			}
		}
	}
    
	SAFE_FREE(err_str);
	SAFE_FREE(msg_str);
	pass = NULL;
	TALLOC_FREE(frame);
	return PAM_IGNORE;
}
Esempio n. 3
0
/* Helper function for adding a user to the db. */
static int _smb_add_user(pam_handle_t *pamh, unsigned int ctrl,
                         const char *name, SAM_ACCOUNT *sampass, BOOL exist)
{
    pstring err_str;
    pstring msg_str;
    const char *pass = NULL;
    int retval;

    err_str[0] = '\0';
    msg_str[0] = '\0';

    /* Get the authtok; if we don't have one, silently fail. */
    retval = pam_get_item( pamh, PAM_AUTHTOK, (const void **) &pass );

    if (retval != PAM_SUCCESS) {
	_log_err( LOG_ALERT
	          , "pam_get_item returned error to pam_sm_authenticate" );
	return PAM_AUTHTOK_RECOVER_ERR;
    } else if (pass == NULL) {
	return PAM_AUTHTOK_RECOVER_ERR;
    }

    /* Add the user to the db if they aren't already there. */
   if (!exist) {
	retval = local_password_change( name, LOCAL_ADD_USER,
	                                 pass, err_str,
	                                 sizeof(err_str),
	                                 msg_str, sizeof(msg_str) );
	if (!retval && *err_str)
	{
	    err_str[PSTRING_LEN-1] = '\0';
	    make_remark( pamh, ctrl, PAM_ERROR_MSG, err_str );
	}
	else if (*msg_str)
	{
	    msg_str[PSTRING_LEN-1] = '\0';
	    make_remark( pamh, ctrl, PAM_TEXT_INFO, msg_str );
	}
	pass = NULL;

	return PAM_IGNORE;
   }
   else {
    /* Change the user's password IFF it's null. */
    if ((pdb_get_lanman_passwd(sampass) == NULL) && (pdb_get_acct_ctrl(sampass) & ACB_PWNOTREQ))
    {
	retval = local_password_change( name, 0, pass, err_str, sizeof(err_str),
	                                 msg_str, sizeof(msg_str) );
	if (!retval && *err_str)
	{
	    err_str[PSTRING_LEN-1] = '\0';
	    make_remark( pamh, ctrl, PAM_ERROR_MSG, err_str );
	}
	else if (*msg_str)
	{
	    msg_str[PSTRING_LEN-1] = '\0';
	    make_remark( pamh, ctrl, PAM_TEXT_INFO, msg_str );
	}
    }
   }
    
    pass = NULL;

    return PAM_IGNORE;
}
Esempio n. 4
0
int pam_sm_acct_mgmt( pam_handle_t *pamh, int flags,
                      int argc, const char **argv )
{
    unsigned int ctrl;
    int retval;

    const char *name;
    SAM_ACCOUNT *sampass = NULL;
    void (*oldsig_handler)(int);
    extern BOOL in_client;

    /* Samba initialization. */
    setup_logging( "pam_smbpass", False );
    in_client = True;

    ctrl = set_ctrl( flags, argc, argv );

    /* get the username */

    retval = pam_get_user( pamh, &name, "Username: "******"acct: could not identify user" );
        }
        return retval;
    }
    if (on( SMB_DEBUG, ctrl )) {
        _log_err( LOG_DEBUG, "acct: username [%s] obtained", name );
    }

    /* Getting into places that might use LDAP -- protect the app
       from a SIGPIPE it's not expecting */
    oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN);
    if (!initialize_password_db(True)) {
        _log_err( LOG_ALERT, "Cannot access samba password database" );
        CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
        return PAM_AUTHINFO_UNAVAIL;
    }

    /* Get the user's record. */
    pdb_init_sam(&sampass);
    pdb_getsampwnam(sampass, name );

    if (!sampass) {
        CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
        return PAM_USER_UNKNOWN;
    }

    if (pdb_get_acct_ctrl(sampass) & ACB_DISABLED) {
        if (on( SMB_DEBUG, ctrl )) {
            _log_err( LOG_DEBUG
                      , "acct: account %s is administratively disabled", name );
        }
        make_remark( pamh, ctrl, PAM_ERROR_MSG
                     , "Your account has been disabled; "
                       "please see your system administrator." );

        CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
        return PAM_ACCT_EXPIRED;
    }

    /* TODO: support for expired passwords. */

    CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
    return PAM_SUCCESS;
}
/* Do the actual work of creating a home dir */
static int create_homedir(pam_handle_t * pamh, int ctrl,
                          const struct passwd *pwd,
                          const char *source, const char *dest)
{
   char remark[BUFSIZ];
   DIR *D;
   struct dirent *Dir;

   /* Mention what is happening, if the notification fails that is OK */
   if (snprintf(remark,sizeof(remark),"Creating directory '%s'.", dest) == -1)
      return PAM_PERM_DENIED;

   make_remark(pamh, ctrl, remark);

   /* Create the new directory */
   if (mkdir(dest,0700) != 0)
   {
      _log_err(LOG_DEBUG, "unable to create directory %s",dest);
      return PAM_PERM_DENIED;
   }   
   if (chmod(dest,0777 & (~UMask)) != 0 ||
       chown(dest,pwd->pw_uid,pwd->pw_gid) != 0)
   {
      _log_err(LOG_DEBUG, "unable to change perms on directory %s",dest);
      return PAM_PERM_DENIED;
   }

   /* See if we need to copy the skel dir over. */
   if ((source == NULL) || (strlen(source) == 0))
   {
      return PAM_SUCCESS;
   }

   /* Scan the directory */
   D = opendir(source);
   if (D == 0)
   {
      _log_err(LOG_DEBUG, "unable to read directory %s",source);
      return PAM_PERM_DENIED;
   }

   for (Dir = readdir(D); Dir != 0; Dir = readdir(D))
   {  
      int SrcFd;
      int DestFd;
      int Res;
      struct stat St;
      char newsource[PATH_MAX], newdest[PATH_MAX];

      /* Skip some files.. */
      if (strcmp(Dir->d_name,".") == 0 ||
	  strcmp(Dir->d_name,"..") == 0)
	 continue;

      /* Determine what kind of file it is. */
      snprintf(newsource,sizeof(newsource),"%s/%s",source,Dir->d_name);
      if (lstat(newsource,&St) != 0)
         continue;

      /* We'll need the new file's name. */
      snprintf(newdest,sizeof(newdest),"%s/%s",dest,Dir->d_name);

      /* If it's a directory, recurse. */
      if (S_ISDIR(St.st_mode))
      {
         create_homedir(pamh, ctrl, pwd, newsource, newdest);
         continue;
      }

      /* If it's a symlink, create a new link. */
      if (S_ISLNK(St.st_mode))
      {
         char pointed[PATH_MAX];
         memset(pointed, 0, sizeof(pointed));
         if(readlink(newsource, pointed, sizeof(pointed) - 1) != -1)
         {
            if(symlink(pointed, newdest) == 0)
            {
               if (lchown(newdest,pwd->pw_uid,pwd->pw_gid) != 0)
               {
                   _log_err(LOG_DEBUG, "unable to chang perms on link %s",
                            newdest);
                   return PAM_PERM_DENIED;
               }
            }
         }
         continue;
      }

      /* If it's not a regular file, it's probably not a good idea to create
       * the new device node, FIFO, or whatever it is. */
      if (!S_ISREG(St.st_mode))
      {
         continue;
      }

      /* Open the source file */
      if ((SrcFd = open(newsource,O_RDONLY)) < 0 || fstat(SrcFd,&St) != 0)
      {
         _log_err(LOG_DEBUG, "unable to open src file %s",newsource);
	 return PAM_PERM_DENIED;
      }
      stat(newsource,&St);

      /* Open the dest file */
      if ((DestFd = open(newdest,O_WRONLY | O_TRUNC | O_CREAT,0600)) < 0)
      {
	 close(SrcFd);
         _log_err(LOG_DEBUG, "unable to open dest file %s",newdest);
	 return PAM_PERM_DENIED;
      }

      /* Set the proper ownership and permissions for the module. We make
       	 the file a+w and then mask it with the set mask. This preseves
       	 execute bits */
      if (fchmod(DestFd,(St.st_mode | 0222) & (~UMask)) != 0 ||
	  fchown(DestFd,pwd->pw_uid,pwd->pw_gid) != 0)
      {
         close(SrcFd);
         close(DestFd);
         _log_err(LOG_DEBUG, "unable to chang perms on copy %s",newdest);
	 return PAM_PERM_DENIED;
      }

      /* Copy the file */
      do
      {
         Res = read(SrcFd,remark,sizeof(remark));
	 if (Res < 0 || write(DestFd,remark,Res) != Res)
	 {
	    close(SrcFd);
	    close(DestFd);
	    _log_err(LOG_DEBUG, "unable to perform IO");
	    return PAM_PERM_DENIED;
	 }
      }
      while (Res != 0);
      close(SrcFd);
      close(DestFd);
   }

   return PAM_SUCCESS;
}
Esempio n. 6
0
int pam_sm_acct_mgmt( pam_handle_t *pamh, int flags,
                      int argc, const char **argv )
{
	unsigned int ctrl;
	int retval;

	const char *name;
	struct samu *sampass = NULL;
	void (*oldsig_handler)(int);

	/* Samba initialization. */
	load_case_tables();
	setup_logging( "pam_smbpass", False );
        lp_set_in_client(True);

	ctrl = set_ctrl( flags, argc, argv );

	/* get the username */

	retval = pam_get_user( pamh, &name, "Username: "******"acct: could not identify user" );
		}
		return retval;
	}
	if (on( SMB_DEBUG, ctrl )) {
		_log_err( LOG_DEBUG, "acct: username [%s] obtained", name );
	}

	if (geteuid() != 0) {
		_log_err( LOG_DEBUG, "Cannot access samba password database, not running as root.");
		return PAM_AUTHINFO_UNAVAIL;
	}

	/* Getting into places that might use LDAP -- protect the app
		from a SIGPIPE it's not expecting */
	oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN);
	if (!initialize_password_db(True, NULL)) {
		_log_err( LOG_ALERT, "Cannot access samba password database" );
		CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
		return PAM_AUTHINFO_UNAVAIL;
	}

	/* Get the user's record. */

	if (!(sampass = samu_new( NULL ))) {
        	CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
		/* malloc fail. */
		return nt_status_to_pam(NT_STATUS_NO_MEMORY);
	}

	if (!pdb_getsampwnam(sampass, name )) {
		_log_err( LOG_DEBUG, "acct: could not identify user" );
        	CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
        	return PAM_USER_UNKNOWN;
	}

	/* check for lookup failure */
	if (!strlen(pdb_get_username(sampass)) ) {
		CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
		return PAM_USER_UNKNOWN;
	}

	if (pdb_get_acct_ctrl(sampass) & ACB_DISABLED) {
		if (on( SMB_DEBUG, ctrl )) {
			_log_err( LOG_DEBUG
				, "acct: account %s is administratively disabled", name );
		}
		make_remark( pamh, ctrl, PAM_ERROR_MSG
			, "Your account has been disabled; "
			"please see your system administrator." );

		CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
		return PAM_ACCT_EXPIRED;
	}

	/* TODO: support for expired passwords. */

	CatchSignal(SIGPIPE, SIGNAL_CAST oldsig_handler);
	return PAM_SUCCESS;
}