Merge remote-tracking branch 'origin/v3.5'

This commit is contained in:
Adolfo Gómez García 2021-10-18 17:09:00 +02:00
commit 9c6a72d3ac
15 changed files with 21 additions and 544 deletions

View File

@ -37,6 +37,7 @@ import typing
class LocalLogger: # pylint: disable=too-few-public-methods
linux = False
windows = True
serviceLogger = False
logger: typing.Optional[logging.Logger]

View File

@ -366,17 +366,19 @@ class CommonService: # pylint: disable=too-many-instance-attributes
'''
hostName = platform.operations.getComputerName()
if hostName.lower() == name.lower():
logger.info('Computer name is already {}'.format(hostName))
return
# Check for password change request for an user
if userName and newPassword:
changed = True
logger.info('Setting password for configured user')
try:
platform.operations.changeUserPassword(userName, oldPassword or '', newPassword)
except Exception as e:
raise Exception('Could not change password for user {} (maybe invalid current password is configured at broker): {} '.format(userName, str(e)))
# Logs error, but continue renaming computer
logger.error('Could not change password for user {}: {}'.format(userName, e))
if hostName.lower() == name.lower():
logger.info('Computer name is already {}'.format(hostName))
return
if platform.operations.renameComputer(name):
self.reboot()

View File

@ -34,7 +34,8 @@ import os
import tempfile
import typing
import servicemanager # pylint: disable=import-error
import servicemanager
from udsactor import service # pylint: disable=import-error
# Valid logging levels, from UDS Broker (uds.core.utils.log).
from .. import loglevel
@ -42,6 +43,7 @@ from .. import loglevel
class LocalLogger: # pylint: disable=too-few-public-methods
linux = False
windows = True
serviceLogger = False
logger: typing.Optional[logging.Logger]

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python3
#!/usr/bin/env python3 -s
# -*- coding: utf-8 -*-
#
# Copyright (c) 2014-2021 Virtual Cable S.L.U.

View File

@ -198,6 +198,9 @@ class Users(DetailHandler):
'staff_member',
'is_admin',
]
if self._params.get('name', '') == '':
raise RequestError(_('Username cannot be empty'))
if 'password' in self._params:
valid_fields.append('password')
self._params['password'] = cryptoManager().hash(self._params['password'])
@ -239,6 +242,8 @@ class Users(DetailHandler):
raise RequestError(str(e))
except ValidationError as e:
raise RequestError(str(e.message))
except RequestError:
raise
except Exception:
logger.exception('Saving user')
raise self.invalidRequestException()
@ -421,6 +426,8 @@ class Groups(DetailHandler):
logger.debug('Meta any %s', meta_if_any)
logger.debug('Pools: %s', pools)
valid_fields = ['name', 'comments', 'state']
if self._params.get('name', '') == '':
raise RequestError(_('Group name is required'))
fields = self.readFieldsFromParams(valid_fields)
is_pattern = fields.get('name', '').find('pat:') == 0
auth = parent.getInstance()
@ -463,6 +470,8 @@ class Groups(DetailHandler):
raise RequestError(_('User already exists (duplicate key error)'))
except AuthenticatorException as e:
raise RequestError(str(e))
except RequestError:
raise
except Exception:
logger.exception('Saving group')
raise self.invalidRequestException()

View File

@ -1,5 +0,0 @@
CMakeCache.txt
CMakeFiles
*.cmake
Makefile
*.so

View File

@ -1,5 +0,0 @@
cmake_minimum_required(VERSION 2.8)
set(CMAKE_BUILD_TYPE Release)
project (UDS_PAM)
add_subdirectory(src)

View File

@ -1,34 +0,0 @@
# Very simple setup file
# We suppose that we already have pam develompent files & curl development files installed
set(pam_uds_SRCS
pam_uds.c
http.c
http.h
)
set(nss_uds_SRCS
shadow.c
passwd.c
group.c
http.c
http.h
)
add_library(pam_uds SHARED ${pam_uds_SRCS})
set_target_properties(pam_uds PROPERTIES
OUTPUT_NAME pam_uds
PREFIX ""
SUFFIX ".so"
)
target_link_libraries(pam_uds curl pam)
add_library(nss_uds SHARED ${nss_uds_SRCS})
set_target_properties(nss_uds PROPERTIES
OUTPUT_NAME nss_uds
PREFIX "lib"
)
# Remember, nss libs needs to have ".so.2" symlink to .so
target_link_libraries(nss_uds curl)

View File

@ -1,42 +0,0 @@
#define _GNU_SOURCE 1
#include <stdio.h>
#include <stdlib.h>
#include <nss.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <ctype.h>
#include <grp.h>
enum nss_status _nss_uds_setgrent (void);
enum nss_status _nss_uds_endgrent (void);
enum nss_status _nss_uds_getgrent_r (struct group *gr,
char * buffer, size_t buflen,int * errnop);
enum nss_status _nss_uds_getgrnam_r (const char * name, struct group *gr,
char * buffer, size_t buflen,int *errnop);
enum nss_status _nss_uds_getgrgid_r (const gid_t gid, struct group *gr,
char * buffer, size_t buflen,int *errnop);
enum nss_status _nss_uds_setgrent (void) {
}
enum nss_status _nss_uds_endgrent (void) {
}
enum nss_status _nss_uds_getgrent_r (struct group *gr,
char * buffer, size_t buflen,int * errnop) {
}
enum nss_status _nss_uds_getgrnam_r (const char * name, struct group *gr,
char * buffer, size_t buflen,int *errnop) {
}
enum nss_status _nss_uds_getgrgid_r (const gid_t gid, struct group *gr,
char * buffer, size_t buflen,int *errnop) {
}

View File

@ -1,138 +0,0 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <curl/curl.h>
#include <curl/easy.h>
#define DATASIZE 256
#define UID "uid"
#define NAME "name"
#define AUTHID "id"
#define AUTHPASS "pass"
struct OutputData {
char* buffer;
size_t size;
size_t pos;
};
static size_t authenticatorData(void *buffer, size_t size, size_t nmemb, void *userp) {
struct OutputData* data = (struct OutputData*)userp;
size_t realSize = size * nmemb;
if( data->pos + realSize >= data->size )
return 0;
memcpy( data->buffer + data->pos, buffer, realSize );
data->pos += realSize;
return realSize;
}
static int getUrl(const char* url, char* buffer, size_t size ) {
CURL *curl = curl_easy_init();
CURLcode res = -1;
struct OutputData* data = malloc(sizeof(struct OutputData));
data->buffer = buffer;
data->size = size;
data->pos = 0;
if (!curl) return -1;
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, authenticatorData);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, data );
/* provide no progress indicator */
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
/* fail on HTTP errors */
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
curl_easy_setopt(curl, CURLOPT_RANDOM_FILE, "/dev/urandom");
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0 );
res = curl_easy_perform(curl);
cleanup:
curl_easy_cleanup(curl);
buffer[data->pos] = '\0';
free(data);
return res;
}
int isValid(const char* str)
{
const int len = strnlen(str, DATASIZE);
int i;
for( i = 0; i < len; i++ ) {
if ( !isalnum(str[i]) && str[i] != '-' ) {
return 0;
}
}
return 1;
}
int httpAuthenticate(const char* username, const char* password, const char* authHost)
{
char* buffer = malloc(DATASIZE);
char* url = malloc(256);
int res;
/* Ensure username & passwords are valid */
if (!isValid(username) || !isValid(password)) {
return -1; /* no valid data, injecting? */
}
sprintf( url, "%s?%s=%s&%s=%s", authHost, AUTHID, username, AUTHPASS, password );
res = getUrl( url, buffer, DATASIZE );
free(url);
if( res == 0 && buffer[0] == '0' )
res = -1;
free(buffer);
return res;
}
static int getUserData( const char* host, const char* kind, const char* id, char* username, int* uid ) {
char* buffer = malloc(DATASIZE);
char* url = malloc(256);
int res;
*username = '\0';
*uid = -1;
sprintf( url, "%s?%s=%s", host, kind, id );
res = getUrl( url, buffer, DATASIZE );
free(url);
if( res == 0 ) {
if( *buffer == '*' )
res = -1;
else {
sscanf( buffer, "%d %s", uid, username );
if( *uid == -1 )
res = -1;
}
}
free(buffer);
return res;
}
int getUID( const char* host, const char* name, char* username, int* uid ) {
return getUserData( host, UID, name, username, uid );
}
int getName( const char* host, int id, char* username, int* uid ) {
char tmp[32];
sprintf( tmp, "%d", id );
return getUserData( host, NAME, tmp, username, uid );
}

View File

@ -1,13 +0,0 @@
#ifndef __HTTP_H_DK__
#define __HTTP_H_DK__
int httpAuthenticate(const char* username, const char* password, const char* authHost);
int getUID( const char* host, const char* name, char* username, int* uid );
int getName( const char* host, int id, char* username, int* uid );
#endif

View File

@ -1,109 +0,0 @@
/* (c) 2020 Adolfo Gómez */
#include <features.h>
#include <syslog.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include "http.h"
#define PAM_SM_AUTH
#include <security/pam_modules.h>
#include <security/_pam_macros.h>
#define UDS_DEBUG 020 /* keep quiet about things */
#define UDS_QUIET 040 /* keep quiet about things */
/* some syslogging */
static void _log_err(int err, const char *format, ...)
{
va_list args;
va_start(args, format);
openlog("PAM-uds", LOG_CONS|LOG_PID, LOG_AUTH);
vsyslog(err, format, args);
va_end(args);
closelog();
}
static char baseUrl[128] = "";
static int _pam_parse(int flags, int argc, const char **argv)
{
int ctrl = 0;
/* does the appliction require quiet? */
if ((flags & PAM_SILENT) == PAM_SILENT)
ctrl |= UDS_QUIET;
/* step through arguments */
for (; argc-- > 0; ++argv)
{
if (!strcmp(*argv, "silent")) {
ctrl |= UDS_QUIET;
} else if (!strncmp(*argv,"base=",5)) {
strncpy(baseUrl,*argv+5,sizeof(baseUrl));
baseUrl[sizeof(baseUrl)-1] = '\0';
_log_err(LOG_ERR, "option base: %s", baseUrl);
} else {
_log_err(LOG_ERR, "unknown option; %s", *argv);
}
}
D(("ctrl = %o", ctrl));
return ctrl;
}
/********************
* PAM
********************/
PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags,
int argc, const char **argv)
{
const char *username;
const char* passwd;
int res;
int rv = PAM_SUCCESS, ctrl;
ctrl = _pam_parse(flags, argc, argv);
if (strlen(baseUrl) == 0)
{
_log_err(LOG_ERR, "Need a host for authentication" );
return PAM_AUTH_ERR;
}
if (pam_get_user(pamh, &username, 0) != PAM_SUCCESS) {
_log_err( LOG_ERR, "Couldn't get username");
return PAM_AUTH_ERR;
}
if( pam_get_item(pamh, PAM_AUTHTOK, (const void **)&passwd) != PAM_SUCCESS ) {
_log_err( LOG_ERR, "Couldn't get password" );
return PAM_AUTH_ERR;
}
if ( (res = httpAuthenticate(username, passwd, baseUrl)) != 0 ) {
_log_err( LOG_ERR, "Failed to check credentials., base = %s, Result = %d", baseUrl, res );
rv = PAM_AUTH_ERR;
}
else {
rv = PAM_SUCCESS;
}
return rv;
}
PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags,
int argc, const char **argv)
{
return PAM_SUCCESS;
}

View File

@ -1,113 +0,0 @@
#define _GNU_SOURCE 1
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <nss.h>
#include <pwd.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <ctype.h>
#include <fcntl.h>
#include <syslog.h>
#include "http.h"
char baseUrl[256] = { '\0' };
enum nss_status _nss_uds_getpwuid_r(uid_t,struct passwd *,char *, size_t,int *);
enum nss_status _nss_uds_setpwent (void);
enum nss_status _nss_uds_endpwent (void);
enum nss_status _nss_uds_getpwnam_r(const char *,struct passwd *,char *,size_t,int *);
enum nss_status _nss_uds_getpwent_r(struct passwd *, char *, size_t,int *);
static enum nss_status p_search(FILE *f,const char *name,const uid_t uid,struct passwd *pw, int *errnop,char *buffer, size_t buflen);
static void read_config(char* host, size_t size) {
int n;
FILE* f = fopen("/etc/uds.conf", "r");
if( f != NULL ) {
fgets( host, size-1, f );
n = strlen(host) - 1;
if( host[n] == '\n' )
host[n] = '\0';
fclose(f);
} else {
host[0] = '\0';
}
}
enum nss_status _nss_uds_getpwuid_r(
uid_t uid,
struct passwd *result,
char *buf,
size_t buflen,
int *errnop
) {
char host[256];
char *dir;
read_config( host, sizeof(host) );
if (result == NULL || buflen < 128 || *host == '\0')
return NSS_STATUS_UNAVAIL;
*errnop = getName( host, uid, buf, &result->pw_uid );
if( *errnop != 0 )
return NSS_STATUS_NOTFOUND;
dir = buf + strlen(buf) + 1;
sprintf( dir, "/var/udstmp", buf );
result->pw_name = buf;
result->pw_passwd = "*"; // This is really not used in our environment :)
result->pw_gid = 65534; // Nogroup
result->pw_gecos = "bugoma";
result->pw_dir = dir;
result->pw_shell = "/bin/false";
return NSS_STATUS_SUCCESS;
}
enum nss_status _nss_uds_getpwnam_r(const char *name, struct passwd *result,
char *buf, size_t buflen, int *errnop) {
char host[256];
char *dir;
read_config( host, sizeof(host) );
if (result == NULL || buflen < 128 || *host == '\0')
return NSS_STATUS_UNAVAIL;
*errnop = getUID( host, name, buf, &result->pw_uid );
if( *errnop != 0 )
return NSS_STATUS_NOTFOUND;
dir = buf + strlen(buf) + 1;
strcpy( dir, "/var/udstmp");
result->pw_name = buf;
result->pw_passwd = "*"; // This is really not used in our environment :)
result->pw_gid = 65534; // Nogroup
result->pw_gecos = "bugoma";
result->pw_dir = dir;
result->pw_shell = "/bin/false";
return NSS_STATUS_SUCCESS;
}
enum nss_status _nss_uds_setpwent (void) {
return NSS_STATUS_SUCCESS;
}
enum nss_status _nss_uds_endpwent (void) {
return NSS_STATUS_SUCCESS;
}
enum nss_status _nss_uds_getpwent_r (struct passwd *pw,
char * buffer, size_t buflen,int * errnop) {
return NSS_STATUS_UNAVAIL;
}

View File

@ -1,49 +0,0 @@
/*
Copyright (C) 2001,2002 Bernhard R. Link <brlink@debian.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation.
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.
Please tell me, if you find errors or mistakes.
Based on parts of the GNU C Library:
Common code for file-based database parsers in nss_files module.
Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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
Lesser General Public License for more details.
*/
#define _GNU_SOURCE 1
#include <stdlib.h>
#include <stdio.h>
#include <nss.h>
#include <string.h>
#include <shadow.h>
#include <time.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <ctype.h>
enum nss_status _nss_uds_getspnam_r (const char *name, struct spwd *spw,
char *buffer, size_t buflen,int * errnop)
{
}

View File

@ -1,29 +0,0 @@
/*
* test.c
*
* Created on: Jan 4, 2012
* Author: dkmaster
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "http.h"
int main(int argc, char** argv)
{
int id;
char username[128];
const char* baseUrl = "http://172.27.0.1:8000/pam";
printf("Authenticate: %d\n", httpAuthenticate("pepito", "juanito", baseUrl));
int res = getUID(baseUrl,"pepito", username, &id);
printf("GetUID:res: %d, username: %s, id: %d\n", res, username, id);
*username = '\0';
res = getName(baseUrl, 10000, username, &id);
printf("GetName:res: %d, username: %s, id: %d\n", res, username, id);
}