Unix программирование. Не уверен, как использовать структуру passwd - PullRequest
5 голосов
/ 23 октября 2009

Я провел некоторые исследования и все еще борюсь со структурой passwd.

http://www.opengroup.org/onlinepubs/000095399/basedefs/pwd.h.html

Мне нужно получить идентификатор пользователя, но я не думаю, что использую его для понимания.

int getpwuid_r (uid_t, struct passwd *, char *, size_t, struct passwd **);

Этот вызов метода возвращает точку в структуру, которая будет содержать все необходимые мне данные. Я довольно запутался в параметрах.

struct passwd. Должен ли я объявить это первым? struct passwd passwd?

Я просто совершенно не знаю, как это использовать.

Наконец, когда я заполню свой указатель. Какие звонки я буду использовать для получения данных? Спасибо за любую помощь.

Ответы [ 3 ]

7 голосов
/ 23 октября 2009

В подписи getpwuid_r:

int getpwuid_r(uid_t uid, struct passwd *pwbuf, char *buf, 
    size_t buflen, struct passwd **pwbufp);

uid - это входной параметр - это UID пользователя, которого вы хотите найти. Остальные по сути являются выходными параметрами: структура, на которую указывает pwbuf, будет заполнена информацией о пароле, а указатель на pwbufp будет установлен на значение pwbuf, если вызов был успешным (и NULL если бы не было). Пара параметров buf и buflen задает пользовательский буфер, который будет использоваться для хранения строк, на которые указывают члены возвращаемой структуры struct passwd.

Вы бы использовали его так (это ищет пользователя с UID 101):

    struct passwd pwent;
    struct passwd *pwentp;
    char buf[1024];

    if (getpwuid_r(101, &pwent, buf, sizeof buf, &pwentp))
    {
            perror("getpwuid_r");
    }
    else
    {
            printf("Username: %s\n", pwent.pw_name);
            printf("Real Name: %s\n", pwent.pw_gecos);
            printf("Home Directory: %s\n", pwent.pw_dir);
    }

Если в момент чтения вам нужно найти пользователя по имени, чтобы найти его идентификатор, используйте getpwnam_r и проверьте поле pw_uid возвращаемой структуры.

1 голос
/ 23 октября 2009

Во-первых, если вы хотите получить UID, то, вероятно, у вас есть имя пользователя под рукой, и в этом случае вы должны использовать getpwnam_r(). Эта функция используется точно так же, как getpwuid_r(), за исключением того, что вы передаете ей имя (char *) в качестве первого параметра.

Во-вторых, вам не нужно объявлять `struct passwd '. Это объявляется, когда вы включаете pwd.h.

В-третьих, точная подпись функции:

int getpwnam_r(const char *name, struct passwd *pwd,
               char *buf, size_t buflen, struct passwd **result);

В приведенном выше примере pwd является параметром output . Здесь функция возвращает ваш пароль, если он найден.

Наконец, есть полный пример того, как использовать getpwnam_r в справочной странице Linux getpwnam_r, доступный здесь .

1 : http://manpages.ubuntu.com/manpages/jaunty/en/man3/getpwnam.3.html здесь

1 голос
/ 23 октября 2009

Хорошо, во-первых, я не слишком уверен, что вы пытаетесь выполнить - вы сказали, что вам нужно получить uid, но getpwuid предназначен для поиска другой информации на основе uid. Возможно, вы хотите получить getpwnam, который ищет в зависимости от имени пользователя? И тогда вам нужно использовать uid для другой функции?

В любом случае все, что я скажу ниже, относится как к getpwnam, так и к getpwuid - просто замените аргумент uid на аргумент username.

Вы немного перепутали документацию. Почти цитата из справочной страницы:

struct passwd *getpwuid(uid_t uid);

int getpwuid_r(uid_t uid, struct passwd *pwbuf, char *buf, size_t buflen, struct passwd **pwbufp);

Функция getpwuid () возвращает указатель на структуру, содержащую разбитые поля записи в базе данных паролей, которая соответствует идентификатору пользователя uid.

Функция getpwuid_r () получает ту же информацию, но сохраняет полученную структуру passwd в пространстве, на которое указывает pwbuf.

Звучит так, будто вы просто немного размыты в отношении указателей в целом. Однако вам не нужно слишком беспокоиться об этой работе, это звучит так, как будто для ваших целей может подойти более простая версия:

struct passwd * my_passwd;
my_passwd = getpwuid(uid);
// or:
// my_passwd = getpwnam(username);

if (my_passwd == NULL) {
    // the lookup failed - handle the error!
} else {
    // the lookup succeeded - do your thing 
    printf("User name: %s\n", my_passwd->pw_name);
    printf("User password: %s\n", my_passwd->pw_passwd);
    ...
}

Обратите внимание, что в этом случае вам не нужно выделять память для указателя, потому что getpwuid возвращает указатель на структуру с выделенной памятью и сохраненной информацией.

Полное определение структуры (имена других членов) находится на странице руководства.

Вторая форма, getpwuid_r, лучше подходит для более тщательной обработки ошибок и управления памятью, но если все, что вам нужно, это быстрый поиск, то все будет в порядке.

...