Beispiel #1
0
int pam_sm_authenticate(pam_handle_t *pamh, int flags,
                        int argc, const char **argv)
{
	unsigned int ctrl;
	int retval, *ret_data = NULL;
	struct samu *sampass = NULL;
	const char *name;
	void (*oldsig_handler)(int) = NULL;
	bool found;

	/* Points to memory managed by the PAM library. Do not free. */
	char *p = NULL;

	/* Samba initialization. */
	load_case_tables();
        lp_set_in_client(True);

	ctrl = set_ctrl(pamh, flags, argc, argv);

	/* Get a few bytes so we can pass our return value to
		pam_sm_setcred(). */
	ret_data = SMB_MALLOC_P(int);

	/* we need to do this before we call AUTH_RETURN */
	/* 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);

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

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

	if (!initialize_password_db(True, NULL)) {
		_log_err(pamh, LOG_ALERT, "Cannot access samba password database" );
		retval = PAM_AUTHINFO_UNAVAIL;
		AUTH_RETURN;
	}

	sampass = samu_new( NULL );
    	if (!sampass) {
		_log_err(pamh, LOG_ALERT, "Cannot talloc a samu struct" );
		retval = nt_status_to_pam(NT_STATUS_NO_MEMORY);
		AUTH_RETURN;
	}

	found = pdb_getsampwnam( sampass, name );

	if (on( SMB_MIGRATE, ctrl )) {
		retval = _smb_add_user(pamh, ctrl, name, sampass, found);
		TALLOC_FREE(sampass);
		AUTH_RETURN;
	}

	if (!found) {
		_log_err(pamh, LOG_ALERT, "Failed to find entry for user %s.", name);
		retval = PAM_USER_UNKNOWN;
		TALLOC_FREE(sampass);
		sampass = NULL;
		AUTH_RETURN;
	}

	/* if this user does not have a password... */

	if (_smb_blankpasswd( ctrl, sampass )) {
		TALLOC_FREE(sampass);
		retval = PAM_SUCCESS;
		AUTH_RETURN;
	}

	/* get this user's authentication token */

	retval = _smb_read_password(pamh, ctrl, NULL, "Password: "******"auth: no password provided for [%s]", name);
		TALLOC_FREE(sampass);
		AUTH_RETURN;
	}

	/* verify the password of this user */

	retval = _smb_verify_password( pamh, sampass, p, ctrl );
	TALLOC_FREE(sampass);
	p = NULL;
	AUTH_RETURN;
}
Beispiel #2
0
/*
 * Do some module- and library-wide intializations
 */
static void
SMBC_module_init(void * punused)
{
    bool conf_loaded = False;
    char *home = NULL;
    TALLOC_CTX *frame = talloc_stackframe();
                
    load_case_tables();
                
    setup_logging("libsmbclient", True);

    /* Here we would open the smb.conf file if needed ... */
                
    lp_set_in_client(True);
                
    home = getenv("HOME");
    if (home) {
        char *conf = NULL;
        if (asprintf(&conf, "%s/.smb/smb.conf", home) > 0) {
            if (lp_load(conf, True, False, False, True)) {
                conf_loaded = True;
            } else {
                DEBUG(5, ("Could not load config file: %s\n",
                          conf));
            }
            SAFE_FREE(conf);
        }
    }
                
    if (!conf_loaded) {
        /*
         * Well, if that failed, try the get_dyn_CONFIGFILE
         * Which points to the standard locn, and if that
         * fails, silently ignore it and use the internal
         * defaults ...
         */
                        
        if (!lp_load(get_dyn_CONFIGFILE(), True, False, False, False)) {
            DEBUG(5, ("Could not load config file: %s\n",
                      get_dyn_CONFIGFILE()));
        } else if (home) {
            char *conf;
            /*
             * We loaded the global config file.  Now lets
             * load user-specific modifications to the
             * global config.
             */
            if (asprintf(&conf,
                         "%s/.smb/smb.conf.append",
                         home) > 0) {
                if (!lp_load(conf, True, False, False, False)) {
                    DEBUG(10,
                          ("Could not append config file: "
                           "%s\n",
                           conf));
                }
                SAFE_FREE(conf);
            }
        }
    }
                
    load_interfaces();  /* Load the list of interfaces ... */
                
    reopen_logs();  /* Get logging working ... */
                
    /*
     * Block SIGPIPE (from lib/util_sock.c: write())
     * It is not needed and should not stop execution
     */
    BlockSignals(True, SIGPIPE);
                
    /* Create the mutex we'll use to protect initialized_ctx_count */
    if (SMB_THREAD_CREATE_MUTEX("initialized_ctx_count_mutex",
                                initialized_ctx_count_mutex) != 0) {
        smb_panic("SMBC_module_init: "
                  "failed to create 'initialized_ctx_count' mutex");
    }


    TALLOC_FREE(frame);
}
Beispiel #3
0
int				/* O - Exit status */
main(int argc,			/* I - Number of command-line arguments */
     char *argv[])
{				/* I - Command-line arguments */
	int             i;	/* Looping var */
	int             copies;	/* Number of copies */
	int             port;	/* Port number */
	char            uri[1024],	/* URI */
	               *sep,	/* Pointer to separator */
	               *tmp, *tmp2,	/* Temp pointers to do escaping */
	               *password;	/* Password */
	char           *username,	/* Username */
	               *server,	/* Server name */
	               *printer;/* Printer name */
	const char     *workgroup;	/* Workgroup */
	FILE           *fp;	/* File to print */
	int             status = 1;	/* Status of LPD job */
	struct cli_state *cli;	/* SMB interface */
	char            null_str[1];
	int             tries = 0;
	bool		need_auth = true;
	const char     *dev_uri;
	TALLOC_CTX     *frame = talloc_stackframe();

	null_str[0] = '\0';

	/*
	 * we expect the URI in argv[0]. Detect the case where it is in
	 * argv[1] and cope
	 */
	if (argc > 2 && strncmp(argv[0], "smb://", 6) &&
	    strncmp(argv[1], "smb://", 6) == 0) {
		argv++;
		argc--;
	}

	if (argc == 1) {
		/*
	         * NEW!  In CUPS 1.1 the backends are run with no arguments
		 * to list the available devices.  These can be devices
		 * served by this backend or any other backends (i.e. you
		 * can have an SNMP backend that is only used to enumerate
		 * the available network printers... :)
	         */

		list_devices();
		status = 0;
		goto done;
	}

	if (argc < 6 || argc > 7) {
		fprintf(stderr,
"Usage: %s [DEVICE_URI] job-id user title copies options [file]\n"
"       The DEVICE_URI environment variable can also contain the\n"
"       destination printer:\n"
"\n"
"           smb://[username:password@][workgroup/]server[:port]/printer\n",
			argv[0]);
		goto done;
	}

	/*
         * If we have 7 arguments, print the file named on the command-line.
         * Otherwise, print data from stdin...
         */

	if (argc == 6) {
		/*
	         * Print from Copy stdin to a temporary file...
	         */

		fp = stdin;
		copies = 1;
	} else if ((fp = fopen(argv[6], "rb")) == NULL) {
		perror("ERROR: Unable to open print file");
		goto done;
	} else {
		copies = atoi(argv[4]);
	}

	/*
         * Find the URI...
         */

	dev_uri = getenv("DEVICE_URI");
	if (dev_uri) {
		strncpy(uri, dev_uri, sizeof(uri) - 1);
	} else if (strncmp(argv[0], "smb://", 6) == 0) {
		strncpy(uri, argv[0], sizeof(uri) - 1);
	} else {
		fputs("ERROR: No device URI found in DEVICE_URI environment variable or argv[0] !\n", stderr);
		goto done;
	}

	uri[sizeof(uri) - 1] = '\0';

	/*
         * Extract the destination from the URI...
         */

	if ((sep = strrchr_m(uri, '@')) != NULL) {
		tmp = uri + 6;
		*sep++ = '\0';

		/* username is in tmp */

		server = sep;

		/*
	         * Extract password as needed...
	         */

		if ((tmp2 = strchr_m(tmp, ':')) != NULL) {
			*tmp2++ = '\0';
			password = uri_unescape_alloc(tmp2);
		} else {
			password = null_str;
		}
		username = uri_unescape_alloc(tmp);
	} else {
		if ((username = getenv("AUTH_USERNAME")) == NULL) {
			username = null_str;
		}

		if ((password = getenv("AUTH_PASSWORD")) == NULL) {
			password = null_str;
		}

		server = uri + 6;
	}

	tmp = server;

	if ((sep = strchr_m(tmp, '/')) == NULL) {
		fputs("ERROR: Bad URI - need printer name!\n", stderr);
		goto done;
	}

	*sep++ = '\0';
	tmp2 = sep;

	if ((sep = strchr_m(tmp2, '/')) != NULL) {
		/*
	         * Convert to smb://[username:password@]workgroup/server/printer...
	         */

		*sep++ = '\0';

		workgroup = uri_unescape_alloc(tmp);
		server = uri_unescape_alloc(tmp2);
		printer = uri_unescape_alloc(sep);
	} else {
		workgroup = NULL;
		server = uri_unescape_alloc(tmp);
		printer = uri_unescape_alloc(tmp2);
	}

	if ((sep = strrchr_m(server, ':')) != NULL) {
		*sep++ = '\0';

		port = atoi(sep);
	} else {
		port = 0;
	}

	/*
         * Setup the SAMBA server state...
         */

	setup_logging("smbspool", DEBUG_STDOUT);

	lp_set_in_client(True);	/* Make sure that we tell lp_load we are */

	load_case_tables();

	if (!lp_load(get_dyn_CONFIGFILE(), True, False, False, True)) {
		fprintf(stderr, "ERROR: Can't load %s - run testparm to debug it\n", get_dyn_CONFIGFILE());
		goto done;
	}

	if (workgroup == NULL) {
		workgroup = lp_workgroup();
	}

	load_interfaces();

	do {
		cli = smb_connect(workgroup, server, port, printer,
			username, password, argv[2], &need_auth);
		if (cli == NULL) {
			if (need_auth) {
				exit(2);
			} else if (getenv("CLASS") == NULL) {
				fprintf(stderr, "ERROR: Unable to connect to CIFS host, will retry in 60 seconds...\n");
				sleep(60);
				tries++;
			} else {
				fprintf(stderr, "ERROR: Unable to connect to CIFS host, trying next printer...\n");
				goto done;
			}
		}
	} while ((cli == NULL) && (tries < MAX_RETRY_CONNECT));

	if (cli == NULL) {
		fprintf(stderr, "ERROR: Unable to connect to CIFS host after (tried %d times)\n", tries);
		goto done;
	}

	/*
         * Now that we are connected to the server, ignore SIGTERM so that we
         * can finish out any page data the driver sends (e.g. to eject the
         * current page...  Only ignore SIGTERM if we are printing data from
         * stdin (otherwise you can't cancel raw jobs...)
         */

	if (argc < 7) {
		CatchSignal(SIGTERM, SIG_IGN);
	}

	/*
         * Queue the job...
         */

	for (i = 0; i < copies; i++) {
		status = smb_print(cli, argv[3] /* title */ , fp);
		if (status != 0) {
			break;
		}
	}

	cli_shutdown(cli);

	/*
         * Return the queue status...
         */

done:

	TALLOC_FREE(frame);
	return (status);
}
Beispiel #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;
	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;
}