Skip to content

Commit

Permalink
Add lsof_select_uid/login
Browse files Browse the repository at this point in the history
  • Loading branch information
jiegec committed Jul 10, 2023
1 parent 6ee7470 commit 28c7fc6
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 44 deletions.
22 changes: 22 additions & 0 deletions include/lsof.h
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,28 @@ enum lsof_error lsof_select_pid(struct lsof_context *ctx, uint32_t pid,
enum lsof_error lsof_select_pgid(struct lsof_context *ctx, uint32_t pgid,
int exclude);

/** Ask lsof to select process by uid
*
* Select process whose user id equals to or not equals to `uid`
*
* You can call this function multiple times to add more search conditions.
*
* \since API version 1
*/
enum lsof_error lsof_select_uid(struct lsof_context *ctx, uint32_t uid,
int exclude);

/** Ask lsof to select process by user login
*
* Select process whose user login name equals to or not equals to `login`
*
* You can call this function multiple times to add more search conditions.
*
* \since API version 1
*/
enum lsof_error lsof_select_login(struct lsof_context *ctx, char *login,
int exclude);

/** Freeze the lsof context
*
* You can only call it once per context. After this call, no more options can
Expand Down
98 changes: 98 additions & 0 deletions lib/lsof.c
Original file line number Diff line number Diff line change
Expand Up @@ -1012,4 +1012,102 @@ enum lsof_error lsof_select_pgid(struct lsof_context *ctx, uint32_t pgid,
int exclude) {
return lsof_select_pid_pgid(ctx, pgid, &Spgid, &Mxpgid, &Npgid, &Npgidi,
&Npgidx, exclude, 0);
}

/* Internal helper for lsof_select_uid/lsof_select_login*/
enum lsof_error lsof_select_uid_login(struct lsof_context *ctx, uint32_t uid,
char *login, int exclude) {
int i, j;
MALLOC_S len;
char *lp;

if (!ctx || ctx->frozen) {
return LSOF_ERROR_INVALID_ARGUMENT;
}

/*
* Avoid entering duplicates.
*/
for (i = 0; i < Nuid; i++) {
if (uid != Suid[i].uid)
continue;
/* Duplicate */
if (Suid[i].excl == exclude) {
return LSOF_SUCCESS;
}

/* Conflict */
if (ctx->err) {
(void)fprintf(ctx->err,
"%s: UID %d has been included and excluded.\n", Pn,
(int)uid);
}
return LSOF_ERROR_INVALID_ARGUMENT;
}

/*
* Allocate space for User IDentifier.
*/
if (Nuid >= Mxuid) {
Mxuid += 10;
len = (MALLOC_S)(Mxuid * sizeof(struct seluid));
if (!Suid)
Suid = (struct seluid *)malloc(len);
else
Suid = (struct seluid *)realloc((MALLOC_P *)Suid, len);
if (!Suid) {
if (ctx->err) {
(void)fprintf(ctx->err, "%s: no space for UIDs", Pn);
}
Error(ctx);
return LSOF_ERROR_NO_MEMORY;
}
}
if (login) {
if (!(lp = mkstrcpy(login, (MALLOC_S *)NULL))) {
if (ctx->err) {
(void)fprintf(ctx->err, "%s: no space for login: ", Pn);
safestrprt(login, ctx->err, 1);
}
Error(ctx);
return LSOF_ERROR_NO_MEMORY;
}
Suid[Nuid].lnm = lp;
} else
Suid[Nuid].lnm = (char *)NULL;
Suid[Nuid].f = 0;
Suid[Nuid].uid = uid;
Suid[Nuid++].excl = exclude;
if (exclude)
Nuidexcl++;
else {
Nuidincl++;
Selflags |= SELUID;
}
return LSOF_SUCCESS;
}

API_EXPORT
enum lsof_error lsof_select_uid(struct lsof_context *ctx, uint32_t uid,
int exclude) {
return lsof_select_uid_login(ctx, uid, NULL, exclude);
}

API_EXPORT
enum lsof_error lsof_select_login(struct lsof_context *ctx, char *login,
int exclude) {
struct passwd *pw;
if (!ctx || ctx->frozen) {
return LSOF_ERROR_INVALID_ARGUMENT;
}

/* Convert login to uid, then call lsof_select_uid_login */
if ((pw = getpwnam(login)) == NULL) {
if (ctx->err) {
(void)fprintf(ctx->err, "%s: can't get UID for ", Pn);
safestrprt(login, ctx->err, 1);
}
return LSOF_ERROR_INVALID_ARGUMENT;
}
return lsof_select_uid_login(ctx, pw->pw_uid, login, exclude);
}
51 changes: 7 additions & 44 deletions src/arg.c
Original file line number Diff line number Diff line change
Expand Up @@ -2046,54 +2046,17 @@ int enter_uid(struct lsof_context *ctx, /* context */
}
#endif /* defined(HASSECURITY) && !defined(HASNOSOCKSECURITY) */

/*
* Avoid entering duplicates.
*/
for (i = j = 0; i < Nuid; i++) {
if (uid != Suid[i].uid)
continue;
if (Suid[i].excl == excl) {
j = 1;
continue;
}
(void)fprintf(stderr,
"%s: UID %d has been included and excluded.\n", Pn,
(int)uid);
err = j = 1;
break;
}
if (j)
continue;
/*
* Allocate space for User IDentifier.
*/
if (Nuid >= Mxuid) {
Mxuid += UIDINCR;
len = (MALLOC_S)(Mxuid * sizeof(struct seluid));
if (!Suid)
Suid = (struct seluid *)malloc(len);
else
Suid = (struct seluid *)realloc((MALLOC_P *)Suid, len);
if (!Suid) {
(void)fprintf(stderr, "%s: no space for UIDs", Pn);
if (nn) {
if (lsof_select_login(ctx, lnm, excl)) {
Error(ctx);
return (1);
}
}
if (nn) {
if (!(lp = mkstrcpy(lnm, (MALLOC_S *)NULL))) {
(void)fprintf(stderr, "%s: no space for login: ", Pn);
safestrprt(lnm, stderr, 1);
} else {
if (lsof_select_uid(ctx, uid, excl)) {
Error(ctx);
return (1);
}
Suid[Nuid].lnm = lp;
} else
Suid[Nuid].lnm = (char *)NULL;
Suid[Nuid].uid = uid;
Suid[Nuid++].excl = excl;
if (excl)
Nuidexcl++;
else
Nuidincl++;
}
}
return (err);
}
Expand Down

0 comments on commit 28c7fc6

Please sign in to comment.