About
RSS

Bit Focus


A note of sudo and the user-setting permission

sudo is the magic word in Unix-like world. It grants normal users with administrator access, right?

Actually, that is not so true. The correct way to describe it, which you can find in man sudo, is that

sudo allows a permitted user to execute a command as the superuser or another user

So how does sudo work to serve that purpose? The answer is the user-setting bit in the permission.

First, let's check the permission of your shell program. Here is an example from my system.

% ls -l $SHELL
-rwxr-xr-x 1 root root 858K  Feb 24 2020 /bin/zsh*

You can see the permission string is -rwxr-xr-x. This is normal, as expected. Then let's take a look at sudo.

% ls -l `which sudo`
-rwsr-xr-x 1 root root 163K  Jul 15 2020 /usr/bin/sudo*

Oh, we can see the permission string is a little uncommon. It is -rwsr-xr-x. An x is replace by an s. That is the user-setting bit. It allows the program is executed with the owner of the file as the effective user.

Technically speaking, at the moment the sudo process is running, it already runs as root (or the system administrator), and it can do whatever it wants. However, for security reasons, of course it validates if the actual user has permission (set in the sudoers file).

Be careful when try the following code and make sure your system is free from unexpected access

Then what if we remove such validations? We can try it by compile a simple shell-like program, and change its permission in the same way sudo has.

The C code is like this

Permanent Link: /p/8 Load full text

Post tags:

 sudo
 Linux

How std::function is implemented [2/2]

There is a performance problem in the simplified implement of std::function we have talked about at the former post, that is a dynamic allocation is called for no matter what wrapped in the function object, and when the copy-constructor is called, which often happens when the function object is saved into a container, another dynamic allocation is fired again. This probably results in heavy performance problem.

So we are now going to see if there are some approaches to avoid dynamic allocations.

We want to get rid of new but we also need polymorphism, so the solution is to maintenance a set of "virtual function" by ourselves. Well this is where we need function pointers.

Permanent Link: /p/7 Load full text

Post tags:

 C++11

Troubleshooting : Upgrade pip3 in Ubuntu 16.04

Generally this post is about to setup a Python3 environment on Ubuntu 16.04. However since there seems a problem in pip so let me name it in the title directly.

I started with a fresh new Ubuntu 16.04 droplet at DigitalOcean and have run these commands.

(As non-root with sudo)

Code Snippet 0-0

$ sudo apt-get update
$ sudo apt-get install python3-pip -y
$ sudo pip3 install -U pip

So pip 10 is installed and things seem fine until here. However when I attempt to run pip3, it crashes with an unclear Python stacktrace.

Code Snippet 0-1

$ pip3 --version

Traceback (most recent call last):
  File "/usr/bin/pip3", line 9, in <module>
    from pip import main
ImportError: cannot import name 'main'

It seems that when apt-installed pip upgrades a pypi pip, the pypi pip will be broken and won't work. And the idea is not to use the system-wide pip but to use a venv pip instead.

So the solution is like this.

Code Snippet 0-2

$ sudo apt-get install python3-venv
$ python3 -m venv $HOME/.venv # or any directory you like
$ export PATH=$HOME/.venv/bin:$PATH

Then the pip in the virtualenv will work.

Code Snippet 0-3

$ which python
/home_directory/.venv/bin/python
$ python --version
python 3.5.2
$ which pip
/home_directory/.venv/bin/pip

Now upgrade pip with itself.

Code Snippet 0-4

$ pip install -U pip
...
$ pip --version
pip 10.0.1 from /home_direcotry/.venv/lib/python3.5/site-packages/pip (python 3.5)

Also, you can add export PATH=$HOME/.venv:$PATH to your .bashrc or .zshrc or anything like that.

Permanent Link: /p/6 Load full text

Post tags:

 Python
 Ubuntu
 Installation

Unicode troubleshooting : strftime in Jinja2

Say, in Python2, if we need to format a datetime object with some unicode in the format, what shall we do?

The following code looks perfect

Code Snippet 0-0

# encoding=utf-8

import jinja2
import datetime

now = datetime.datetime.now()

print(jinja2.Template(u'''{{ date.strftime('%Y 年 %m 月') }}''').render(date=now))

Except that it raises a UnicodeEncodeError.

Code Snippet 0-1

Traceback (most recent call last):
  File "test.py", line 8, in <module>
    print(jinja2.Template(u'''{{ date.strftime('%Y 年 %m 月') }}''').render(date=now))
  File "/usr/local/lib/python2.7/dist-packages/jinja2/environment.py", line 1008, in render
    return self.environment.handle_exception(exc_info, True)
  File "/usr/local/lib/python2.7/dist-packages/jinja2/environment.py", line 780, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "<template>", line 1, in top-level template code
UnicodeEncodeError: 'ascii' codec can't encode character u'\u5e74' in position 3: ordinal not in range(128)

So what's wrong with that? The reason is that many standard libraries in Python2 don't have good support to unicode. What a cruel fact.

Well, since we have declared that the file is encoded with UTF-8, how about directly using a str instead of a unicode?

If we use only the standard library it actually works.

Code Snippet 0-2

# encoding=utf-8

import datetime

now = datetime.datetime.now()

print(now.strftime('%Y 年 %m 月'))

This would produce a desired output. So you may think let's remove the prefix u and the template rendering becomes fine, right?

Unfortunately, to do so will get you a UnicodeDecodeError like this

Permanent Link: /p/5 Load full text

Post tags:

 Python

How std::function is implemented [1/2]

This article is about how std::function is implemented and provide some implements that compiled in pre-C++11.

The std::function in C++11 is very fantastic as in a static compiling language like C++ it provides a set of interfaces to wrap any kind of callable objects. A more fantastic fact is that the only C++11 feature that std::function involves is variadic template.

So if we implements a simplified version of std::function with an arbitrary number of template parameters (say, 3 parameters, 1 for the return type and 2 for parameter types), it could be done in pre-C++11 so we don't have to learn the C++11 features right now.

Let us get down to the implements.

0. One pointer version

The std::function could be implemented as a class with only one pointer as its only data member, and of course several virtual functions.

The key point is to declare a virtual base class which could be used to wrap any kinds of callable object, like this.

Permanent Link: /p/4 Load full text

Post tags:

 C++

Configurations Trouble Shooting for Postgres 9 on CentOS 7

0. Change the Data Directory

For some reason the -D or --pgdata arguments passed to initdb command doesn't work. The solution is modifying /etc/init.d/postgres-X.Y, changing this line

PGDATA=path

And run initdb again (of course -D or --pgdata is not necessary any more).

1. Access Control

The network access is set as ident after installation. If you want to use username/password to login the database, which is much easier (but may have some security problems as you need to keep the password carefully), you need to change ... well the file name is not explicitly documented. You are supposed to execute the following command to find it out.

show hba_file

Postgres will give you the path where the configure file locates (usually a pg_hba.conf file). Open that file, modifying this line

# host  all    all     127.0.0.1/32   ident
# change it to
host    all    all     127.0.0.1/32   password

Clarification: you must use the postgres user (the UNIX user) to login your localhost Postgres server to execute show hba_file, as all other users are required to provide the ident in this case.

You might have noticed that the IP address is 127.0.0.1 in that file. This address means all connections from 127.0.0.1 (the localhost) are required to provide the username/password. If you have several hosts in your internal network, you may need change that address into this (assume your internal network has addresses in the pattern of 192.168.*.*)

host    all    all     192.168.0.0/16   password

Permanent Link: /p/3 Load full text

Post tags:

 Postgres
 CentOS

Traits in Generic Programming

Suppose we're going to construct a container, and need combining traits at the compile time. There are some ways to make it, for example, we may use several bools
template <bool AllowDuplicate, bool SortElements, bool CheckOutOfRange>
struct just_another_container;
To use that code will become some sort of nightmare, since every parameter is a bool, if you make a mistake on the order of arguments, you could hardly discover it before the program goes mad.
Another approach is, to merge all bools to a single unsigned, like
template <unsigned Policy>
struct just_another_container;
But that is not good too, since in the first place we have to define some flags
enum {
    ALLOW_DUP_MASK = 1,
    SORT_ELE_MASK = 2,
    CHECK_OUT_OF_RANGE_MASK = 4,
};
and then to use those flags, say, consider we add an insert interface to the container, which is concerned about whether or not allows duplicated elements in the container, the code may look like
void insert(element_type e)
{
    _insert<Policy & ALLOW_DUP_MASK>(e);
}

template <>
void _insert<0>(element_type e);

template <>
void _insert<ALLOW_DUP_MASK>(element_type e);
However unfortunately that won't compile, because C++ forbid specialize template functions (whether partial or not). So, we have to put that _insert into a template struct, like
template <unsigned AllowDuplicate>
struct insert_s
{
    static void insert(just_a_container& container, element_type& e);
};

template <>
struct insert_s<ALLOW_DUP_MASK>
{
    static void insert(just_a_container& container, element_type& e);
};

Permanent Link: /p/2 Load full text

Post tags:

 Generic Programming
 Template
 C++

Leap Year Determination

At Wikipedia we may see a straightforward way to tell whether a year is leap or not. Well here is a more "compact" way (pseudocode)
func is_leap_year(year)
    return (year MOD 4) XOR (year MOD 100) XOR (year MOD 400)
where MOD is modulo, and XOR is exclusive or.

Permanent Link: /p/1 Load full text

Post tags:

 Algorithm

Page 0 1


. Back to Bit Focus
NijiPress - Copyright (C) Neuron Teckid @ Bit Focus
About this site